So, here's my problem:

I have a turret attached to a ship that moves at a variable speed through my game world, shooting at the centre of another ship travelling through the game world in a possibly different vector. Currently, I get the angle that I need to shoot at using atan2:

double targetAngle = Math.Atan2(ship.CurrentTarget.Position.Y - ship.Position.Y, ship.CurrentTarget.Position.X - ship.Position.X);

This works fine when both ships are stationary, or moving very slowly, but if moving faster, the aim lags behind. An additional fun part of the puzzle: the bullet's vector isn't static, they start at 0 and increase in speed. Their position is calculated as follows:

var direction = new Vector2((float)Math.Cos(currentRotation), 

            if (direction.Length() > 0)

            var velocity = new Vector2(direction.X * MotionData.CurrentSpeed,
                direction.Y * MotionData.CurrentSpeed) + additiveVector;

Where additiveVector is my ship's vector at the point the projectile was launched. CurrentSpeed will be added to every frame until it hits a static maxspeed.

So far, the problems I've encountered with other solutions for compensating my aim is that the formulas rely on a static velocity for the projectile, and mine isn't.

  • \$\begingroup\$ I'd say you have to set up an equation you then have to solve. Try to set up functions projectile(t) and target(t). Ptojectile(t) is dependent on your aim angle. You'll have 2 unknown variables (alpha and t). Then you'll have to try to find a solution using mathematical means. You could run into problems setting up the projectile function because it obly accelerates to a max value. You could try making is asymptotic to simplyfy your math. Just something to think about. \$\endgroup\$ – LukeG Nov 17 '15 at 9:50

Your main problem is that you have two objects (ships) and they move with different speeds and a third object that speeds up over time and you want to know the point where you have to aim to hit the ship. With this question you get the same question like military programmers - and you have a lot of variables and never a 100% chance to know the real point.

You break it to just the moving part and not include wind, waves and so on - that makes it easier but not easy.^^

You have 5 variables in this formula:

  • ship-angles (2) the angle of each ship can change(?) - if they start a turn
  • ship-speeds (2) the speed of each ship increases to a maximum
  • bullet-speed (1) the speed of the bullet increases over time

The first effect the possible positions to hit the other ship, the last is important to know how long does the bullet fly over the given distance and how this time has to change the angle.

To solve this you have two ways, I know:

1. Table

The first solution could be something like a table/matrix where you define multiple value pairs and look up with the current ones how your angle should be - this will result in a lower chance to hit the other ship but is fast.

2. Calculation

The second is, like you tried it, a complex formula to calculate with all parameters the correct aim point.

Some ideas for this:

  1. get the current distance between the two ships and the time your bullet needs
  2. calculate the speed difference of both ships to know if you or the other ship will be ahead in the time of step 1 - with this info you know if you have to adjust the angle positive or negative and you know, cause of the time of step 1, how much meters the difference will be
  3. get the angle between the two ships - if they are not parallel you have to adjust the distance your bullet have to fly cause the other ship comes closer or further to you

With these infos you should have all parameters solved your calculation needs - with these infos you can get the coordinate of the other ship if your bullet should hit. And then you can calculate the angle for your turret/bullet to the provided coordinates and not the current position of the ship.

  • \$\begingroup\$ +1 for the last 3 points, that's the gist of what you need to calculate. Get the time, adjust angle based on new positions, and use that new angle. Should fit in your system perfectly. \$\endgroup\$ – Premier Bromanov Jan 26 '16 at 19:00

To expand on (one way you could do) the mathematics behind @Gummibeer's answer..

Keep in mind this physics calculation

d = vt + 1/2at2
distance = initialVelocity*time + 1/2 acceleration * time2

Say your turret is at [0,0] and the enemy is at [10,0] and..
Say your bullet starts at 0 velocity, and accelerates at 1 unit/sec/sec

If we aim at where the enemy was, the totalDistance is 10 units. Lets also say that our acceleration is a simple 1 [unit] per second, per second. (One important note is to keep all distances and all time frames on the same scale)

10 = 0*time + 1/2 1 * time2 ...
10 = 1/2 * time2...
20 = time2
time = 4.4721359 seconds

So, we now know that the target has that amount of time to change their position. There are numerous strategies you could use to go about guessing where they would move to in that period of time. The simplest would be to take their current velocity, assume they will continue at that velocity, and recalculate to that new position.

However, note that there is a paradox here which prevents you from finding the exact time and position of collision with the target, though you can get very close. By recalculating at their new position, there will be a change in the time calculation, which means you could recalculate to their adjusted position after that, and after that, and after that - each iteration getting more and more precise, but never reaching complete 100% accuracy. This is one of Zeno's paradoxes - Achilles and the tortoise.


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.