Today I added homing missiles to my Space Invaders game. This is how I upgraded my code from basic bullets to homing missiles
Lets assume I had the below class for Bullets.
Class bullet
Field x:float,y:float
Field a:float
Field speed:float
Method update:void()
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
Method draw:void()
DrawOval x-10,y-10,20,20
end
End
Each bullet has it x and y co-ordinate for the screen, angle it travels at and speed. On each game loop, it will update its position
But thats a simple bullet. How do we turn this into a homing missile?
Well the first step is to add a target
Class bullet
Field x:float,y:float
Field a:float
Field speed:float
Field tx:float,ty:float
Next we need to find the angle between the current position and the target.
Method update:void()
Local ta:float = ATan2(x-tx,y-ty)
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
ATan2 will gives the angle into one of the 4 quadrants and return a result between -180 and 180 degrees. We'll now shift that between 0-360 degrees
Method update:void()
Local ta:float = ATan2(x-tx,y-ty)
if ta<0 then ta=ta+360
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
So now we know the angle of the target from this 'bullet', we also know the angle we are travelling at. If we compare the 2 we can adjust our travelling angle
Method update:void()
Local ta:float = ATan2(x-tx,y-ty)
if ta<0 then ta=ta+360
if a<ta then a=a+5
if a>ta then a=a-5
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
If we ran this we would get homing missiles taking the long way round when turning as the code doesn't recognise the shortest route is sometimes above 360 to get to angles in the lower range and also sometimes below 0 to get tot he top range
Its all about the shortest route......
We can do an extra test and see that if the shortest way is going below 0 back to 360 or the normal way and increasing.
Method update:void()
Local ta:float = ATan2(x-tx,y-ty)
if ta<0 then ta=ta+360
if a<ta
' test for shortest route
if (a+360-ta) < (ta-a)
a=a-5
' keep angle between 0 and 360
if a<360 then a=a+360
else
a=a+5
end
end
if a>ta then a=a-5
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
and now lets do the same for above 360...
Method update:void()
Local ta:float = ATan2(x-tx,y-ty)
if ta<0 then ta=ta+360
if a<ta
' test for shortest route
if (a+360-ta) < (ta-a)
a=a-5
' keep angle between 0 and 360
if a<0 then a=a+360
else
a=a+5
' keep angle between 0 and 360
if a>360 then a=a-360
end
end
if a>ta
' test for shortest route
if (a+360-ta) < (a-ta)
a=a+5
' keep angle between 0 and 360
if a>360 then a=a-360
else
a=a-5
' keep angle between 0 and 360
if a<0 then a=a+360
end
end
x=x+Sin(a)*speed
y=y+Cos(a)*speed
end
and there we have it.. obviously we are still drawing a round bullet. Lets make it an angled rectangle
Method draw:void()
PushMatrix()
Translate x,y
Rotate a
DrawRect x-5,y-20,10,40
PopMatrix()
end
Comments
Post a Comment