I'm developing a basic vertical shoot em up on the DS and am trying to get stationary turrets to shoot at the player in a shoot em up. Early on I simply had them shooting in fixed 8 directions N, S, E W, NE, NW, SE, SW, depending on the player's relative position, but I want something more specific. My attempts have been awkward at best, and my aiming algorithm is not very crude and often the turrets miss by a mile. I am looking for a simple algorithm that plots a basic straight line trajectory towards the player's xy position. Nothing fancy like predictive aiming. Does anybody know of an algorithm or an article that covers such an algorithm?
2 Answers
Luckily it's pretty simple!
To have a turret shoot a bullet at a target point, you need to figure out the normalized vector from the turret to the target.
To get this, first subtract the target point from the turret point. This gives you a vector but the length is not normalized. To normalize this vector, you just divide x and y by the length of the vector.
Now you have a vector that has a length of 1, that points from the turret to the target.
If you multiply this normalized vector by the speed you want it to move per frame, you then can spawn a bullet at the turret and move it this amount every frame. It will move from the turret to the players position at the appropriate speed.
Like you pointed out though, this is not predictive, and if the player moves, the bullet will miss.
-
\$\begingroup\$ Ok just checking-- when you say 'divide x and y by the vector' does that mean divide each distance by the hypotenuse if I were to triangulate? \$\endgroup\$– SkywarpCommented Jul 13, 2015 at 1:41
-
\$\begingroup\$ Right exactly. You get the length of the hypotenuse (which is the length of the vector) then you divide x and y by this value to normalize it. The vector will then have a length of 1 which is nice because then you can scale it up (or down) to any desired speed by multiplying x and y by the desired speed. \$\endgroup\$ Commented Jul 13, 2015 at 1:44
-
\$\begingroup\$ OK I ran into a problem: the DS doesn't perform floating point arithmetic, so when I divide the x and y distances by the vector the results truncate to zero. The bullets literally just float in one spot now. Is there a workaround for this? \$\endgroup\$– SkywarpCommented Jul 13, 2015 at 2:38
-
\$\begingroup\$ I shipped a ds game so I am sympathetic hehe. One solution is to use fixed point math. Another solution would be to get the vector length to normalize, but multiply by the desired speed before dividing by the vector length. Another way would be to work with angles instead of vectors. Atan2 of the vector from turret to target will give you an angle, then you could do trig stuff. I think fixed point is the most reasonable solution, but might be hard if you have a whole lot of existing code that works only with integers. \$\endgroup\$ Commented Jul 13, 2015 at 2:42
-
\$\begingroup\$ Also you might have some luck if you Frankenstein something using bresenhams line drawing algorithm. It works only with integers and traces a path on a grid so might have some play here for you. Probably will be quite a bit of work, but here's more info if you are interested: blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms \$\endgroup\$ Commented Jul 13, 2015 at 2:44
This can be achieved using trigonometry and vector mathematics. First, calculate the direction (or normalized vector) that the turret should face:
Where a
is the target vector subtracted by the turret position:
direction = Vector2.Direction(targetPos - turretPos);
Assign this value to a Vector2 direction
inside your bullet class. You should to increment your bullet position by its direction:
bullet.position += bullet.direction;
You won't need to update the direction unless you want the bullet to seek the target like a missile. The same direction code can be used to define the turret's rotation.