I'm shooting out a projectile and I want another projectile to closely follow it. I can't simply shoot out the second projectile at a slightly lesser time because the first projectile may change trajectory.

All I want is the second projectile to be closely following behind the first projectile.

My first idea was to plot the points every frame to follow the first projectile. However, as the speed of the first projectile increases, the following projectile lags behind.


If the first projectile has a position and a velocity vector, then you can set the 2nd one's position like this:

bullet2_position = bullet1_position - (normalized_bullet1_velocity * trailing_distance);

You can still apply all the physics you want to the 1st projectile, you just don't need to repeat it all for the 2nd.

  • \$\begingroup\$ unfortunately this method doesn't work at an apex, i.e. when the projectile goes from upwards to downwards. \$\endgroup\$ – meds Dec 16 '10 at 15:58
  • \$\begingroup\$ @meds It should work. Do you mean that the second one should follow the exact path that the first one took? In that case it's much more complicated. If you just want the second to follow the first like a homing missile, then this solution works. But it would probably follow a different path than the first. \$\endgroup\$ – Tesserex Dec 16 '10 at 17:04
  • \$\begingroup\$ A homing missile system is simple to do, I want the second projectile to follow the same trajectory as the first one, the problem is when the first projectile hits an apex it has a zero vertical velocity and its next velocity is downwards which means the following projectile will never reach the apex. \$\endgroup\$ – meds Dec 16 '10 at 17:10
  • \$\begingroup\$ This answer won't follow like meds wants, or like a homing missile. A homing missile would move bullet2 along the vector between bullet1 and bullet2; this moves bullet2 along a vector totally unrelated to its current position, and except in perfectly linear cases, along one that bullet1 itself probably never travelled. \$\endgroup\$ – user744 Dec 16 '10 at 18:14
  • \$\begingroup\$ There could be a problem at apex if bullet 1 has zero velocity, it would NaN when the normalization is done. When I suggested this method, I was picturing in my mind more like an artillery shell that doesn't ever get to zero velocity until impact. But to worry about it following the "exact" path seems a little anal for a game... There is much about game dev that is a compromise between accuracy & performance. Are you sure you need nose hair accuracy like that? \$\endgroup\$ – Steve H Dec 16 '10 at 21:32

What you are looking for is a sort of velocity match between the two objects. You can obtain it by checking the target (first projectile) velocity and modifying the second one according to this.

The pseudo code is something like:

variables: target_velocity, this_velocity, time_to_match and max_acceleration. First and second values are the current velocities of projectiles and other twos are used to tweak the behavior of the chase. Of course you should use vectors (but I suppose you do, since it's the only way to manage these things).

Then at every update:

 result_acceleration = target_velocity - this_velocity;
 result_acceleration /= time_to_match;
 if (result_acceleration.magnitude() > max_acceleration)
   result_acceleration *= max_acceleration;

Then the result_acceleration value is applied as usually within a physics engine to current this_velocity of following projectile. In your case the time_to_match variable should be enough small to keep the two objects tights (eg. 0.05-0.1).

  • \$\begingroup\$ unfortunately this method doesn't work at an apex, i.e. when the projectile goes from upwards to downwards. \$\endgroup\$ – meds Dec 16 '10 at 15:59

Your first idea was good. All you have to do, is take into account the distance between the points the first bullet traveled on each frame, and make sure the second one travels the same distance each frame, meaning that it might "skip" some of the points plotted by the first projectile, or plot some points of its own to match the speed of the first projectile.

positions = [leader.position]
each frame:

     # Loop backwards through the logged positions to find the one
     # the desired distance away.
     d = 0
     i = len(positions) - 1
     while i > 0 and d < follow_distance:
         d += distance(positions[i - 1], positions[i])
         i -= 1

     # Make sure we have enough total distance to start following.
     if d >= follow_distance:
         # In the loop we probably overshot backwards, interpolate
         # forward to the right position.
         p = (d - follow_distance) / distance(positions[i], positions[i + 1])
         follower.position = positions[i] * (1 - p) + positions[i + 1] * p

         # Clear out unneeded positions.

A trivial optimization would be using a deque instead of a list (I don't know if Flash has deques).

The second projectile is going to act really weird though. Like, if it's following a parabola, it's going to slow and come to a stop in mid-air, then continue upwards very slowly, then fall very fast. Is that really what you want?


If you are sure you don't want to just spawn another close behind and follow normal physics, then save the first projectile's previous position with the desired delay and use that value.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.