Getting Angles Between Two Objects with `atan2`
2024-11-21 in codexGoal
Fire a projectile between two objects. The projectile should be “aimed” at the target object, but should not track the target if it moves.
Solution
How it Works
We have two objects in the game. In this case the orange guy and the red guy. First things first, we’ll need a way to get the angle from the orange guy (src
) to the red guy (tgt
).
function get_angle(src,tgt)
local y2=tgt.pos.y
local x2=tgt.pos.x
local y1=src.pos.y
local x1=src.pos.x
return atan2(y2-y1,x2-x1)
end
I won’t (ok, can’t) explain what atan2() does exactly, but I do know that if we give it the y
distance between our objects, followed by the x
distance, we’ll get the angle between the two objects
(something between 0 to 1). Trig, right?
So next we create a bullet object that has an angle and speed:
function fire_bullet(src,tgt)
local bt={}
bt.spr=3
bt.x=src.x
bt.y=src.y
bt.ang=get_angle(src,tgt)
bt.speed=2
add(bullets,bt)
end
With the angle and speed attached to each bullet in the bullets
table we just need to make sure they move using sin()
and cos()
on the x
and y
on every frame.
-- in our update()
for bt in all(bullets) do
bt.x += sin(bt.ang) * bt.speed
bt.y += cos(bt.ang) * bt.speed
end
I hear you saying “what the hell do sin()
and cos()
have to do with moving bullets on an angle?” Good question! I did my best to explain that here: Sin and Cos for Movement.