Given are a twodimensional space, and 1 friendly spaceship standing still, one foe is moving NOT directly to the friendly ship with known actual position, speed and direction.

The friendly ship wants to get itself into firing range to battle the foe.

Actually I am setting just a direct vector to the actual position moving ship, and recalculate it every frame, resulting in some kind of "round" flightpath.

What I want is to set a direct and straight path to the position that the foe will (presumably) will have when firing distance will be reached, assuming that foe will not change course until then.

As a first and "simple" implementation it would be enough if we assume the friend can speed up from 0 to max in no time.

Preffered implemantation would be one that considers the acceleration capabilities of the friend, and knows when interception is impossible because of the speed. It should work for every starting speed, not only from stand still. A plus would be if it even considers braking (battling at lightspeed is very energy inefficient in the given universe)


If I understand your question, you do not want the ship to steer to the target, but rather to fly in a straight line that happens to intercept the target. I'm making a tower defense game that basically has the same need for a tower's bullet, a tower wants to fire a gun such that the bullet will intercept a moving target as long as it doesn't change speed/direction. The way I solved it was by using a quadratic equation. Here is some pseudo code:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
    t = t2;
    t = t1;

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

I found this to work so well I did not need collision detection for the shot... I was able to count on every shot hitting a bulls eye regardless of distance/direction/speed of target as long as those factors remained steady.

| improve this answer | |
  • \$\begingroup\$ From your description this seems to be what I am searching for, at least the easy way assuming instant acceleration to max speed. I'll take a closer look at this in the evening. Am I assuming right that Vector.Dot returns the dotproduct of the to vectors? \$\endgroup\$ – NobbZ Jul 7 '11 at 12:33
  • \$\begingroup\$ Hmmm... I have done this in ruby now, but there seems something wrong. Everytime I try, there is an exception thrown, because the expression in the sqrt evaluates to something negativ and is therefore out of bounds. How can I handle this. Sorry for the question, but I can only use this, but dont understand the conepts here until someone give me an advice. \$\endgroup\$ – NobbZ Jul 7 '11 at 16:09
  • \$\begingroup\$ The example was from this book:amazon.com/… \$\endgroup\$ – Steve H Jul 7 '11 at 17:43
  • 1
    \$\begingroup\$ don't know if this helps but here is some python code that accomplishes the same thing. moddb.com/mods/wicmw/tutorials/… \$\endgroup\$ – Steve H Jul 7 '11 at 17:44
  • \$\begingroup\$ OK, I still does not understand the hole mathematics behind, but thx for the python code, the documentation told me, that if there is a negativ value inside the sqrt, then my friend is to slow to catch up. After tweaking my test values I get some results. Thx for your help. \$\endgroup\$ – NobbZ Jul 7 '11 at 19:31

I suggest you look into steering behaviors. Especially pursuit. Source-code can be found in the OpenSteer implementation or look up a book like "Programming game AI by example" (ISBN 13: 978-1556220784)

| improve this answer | |
  • \$\begingroup\$ pursuit seems to need knowledge about the target and steers towards that, but I dont know the target really. I know where foe is now, I know its speed and its direction. Now I want to know which direction it has to go to intercept foe on its way to its target as soon and fast as possible. As mentioned before acceleration can be ignored at first, this would even save much of processing time compared to the actual version... With the new model I have to recalculate only when the foe fires a "coursechange"-event, not for every "hasmoved"-event as I do it now. \$\endgroup\$ – NobbZ Jul 6 '11 at 19:03
  • \$\begingroup\$ Yes, what you describe is pursuit. It doesn't know the target.. it makes a prediction based on the "foes" current location, speed and direction \$\endgroup\$ – bummzack Jul 6 '11 at 20:18
  • \$\begingroup\$ Then I have missunderstood the description, I'll take a closer look at it tomorrow. \$\endgroup\$ – NobbZ Jul 6 '11 at 20:45
  • \$\begingroup\$ I just finished reading the document a few minutes ago, pursuit is NOT what I am searching for. It is like my actually implementation, except it targets the the position of the next frame, I still have to recalculate the new course every frame and the course is resulting in some curve. But what I want is the direct line assuming foe does not change speed or course until both meet. If this is still not clear enough I try to draw what I want after work. But thanks for the links anyway. I think I can use this somewhere else in the project. \$\endgroup\$ – NobbZ Jul 7 '11 at 11:27
  • \$\begingroup\$ @NobbZ I'm sorry my answer wasn't helpful. You should maybe edit your question accordingly, because statements like: "I know, that in case of change of speed or course of the foe every calculation has to be repeated" can be misleading.. if you did that, you would end up having the "pursuit" steering behavior. \$\endgroup\$ – bummzack Jul 7 '11 at 12:31

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.