# Efficiently detect shoot direction with gravity playing a role?

This topic is 917 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey,

how could I efficiently calculate shoot direction for enemy AI in order for it to hit the player? Things I know:

player position, player velocity, gravity, bullet spawn position, bullet initial velocity/speed(not direction, gravity is also applied for it)

Edited by Gintas Z.

##### Share on other sites

If you ignore air resistance, the player and the bullet follow paraboles. You seem to be look for the crossing point of two paraboles. That sounds like a solved problem to me.

On the other hand, just shooting and hitting the player at exactly the right spot every single time isn't much fun, so you probably want to add some randomness into it. You could also consider using a straight line for the bullet, which reduces the problem to finding the crossing point between a parabole and a straight line. Add some compensation based on distance, and some random for spreading the fire somewhat.

Theoretically, compensation should also take angle of firing into account, but you can overcompensate a bit, and the remaining difference will get lost in randomness anyway.

EDIT:

You can also cheat, and always shoot the player at a known height. That means you can pre-compute the  time delay between firing and hitting a spot at the desired height at a given distance. You can also compute when the player is at that height, and how close he is to the AI then.

Edited by Alberth

##### Share on other sites

A formula to guess the position is:
x = posX + velX * time + 0.5 * gravX * time * time;

So we could get X intersection time:

bulletPosX + bulletVelX * time + 0.5 * gravX * time * time = playerPosX + playerVelX * time + 0.5 * gravX * time * time

Then get the time from Y parabolas. Then do something, but doesn't matter what yet, because how the hell do I extract time out of this mess?

Or is there a different way?

Edited by Gintas Z.

##### Share on other sites
bulletPosX + bulletVelX * time + 0.5 * gravX * time * time = playerPosX + playerVelX * time + 0.5 * gravX * time * time

<==> (subtract '0.5 * gravX * time * time' from both sides)

bulletPosX + bulletVelX * time = playerPosX + playerVelX * time

<==>

(bulletVelX - playerVelX) * time = playerPosX - bulletPosX

<==>

time = (playerPosX - bulletPosX) / (bulletVelX - playerVelX)

?

##### Share on other sites

You have a system of 5 equations and 5 unknowns:

X, Y, bullet_velocity_x, bullet_velocity_y, t are unknown.

Bullet velocity is a shooting direction times initial bullet speed.

Or do you want the solution?

Edited by Alex Mekhed

##### Share on other sites

@Alberth, damn feeling stupid now, didn't notice that. Ok, so should I be doing it like this?

                float timeX = (aimingAtPlayer.getPosX() - bulletSpawnPos.x) / (bulletVelocity.x - aimingAtPlayer.getVelocity().x);
float timeY = (aimingAtPlayer.getPosY() - bulletSpawnPos.y) / (bulletVelocity.y - aimingAtPlayer.getVelocity().y);

float first = bulletSpawnPos.x + bulletVelocity.x * timeX + 0.5f * Constants.WORLD_GRAVITY.x * timeX * timeX;
float second = aimingAtPlayer.getPosX() + aimingAtPlayer.getVelocity().x * timeX + 0.5f * Constants.WORLD_GRAVITY.x * timeX * timeX;
float third = bulletSpawnPos.y + bulletVelocity.y * timeX + 0.5f * Constants.WORLD_GRAVITY.y * timeX * timeX;
float fourth = aimingAtPlayer.getPosY() + aimingAtPlayer.getVelocity().y * timeX + 0.5f * Constants.WORLD_GRAVITY.y * timeX * timeX;
if(Math.abs(first - second) < 0.1f && Math.abs(third - fourth) < 0.1f)
{
isAimingAtPlayerBlocked = false;
// gather direction from vector2(first, second) or vector2(third, fourth)
}
else
isAimingAtPlayerBlocked = true;


And then do the same checking thing with timeY instead of timeX? Is this mess even efficient? No better way?

Edited by Gintas Z.

##### Share on other sites
bulletPosX + bulletVelX * time + 0.5 * gravX * time * time = playerPosX + playerVelX * time + 0.5 * gravX * time * time

<==> (subtract '0.5 * gravX * time * time' from both sides)

bulletPosX + bulletVelX * time = playerPosX + playerVelX * time

<==>

(bulletVelX - playerVelX) * time = playerPosX - bulletPosX

<==>

time = (playerPosX - bulletPosX) / (bulletVelX - playerVelX)

?

bulletVelX is unknown

##### Share on other sites

@Alex it is known. I listed all the things I know in the first post.

##### Share on other sites

And then do the same checking thing with timeY instead of timeX? Is this mess even efficient? No better way?
Shouldn't timeX == timeY (with some epsilon) ?

That would mean you don't need anything but the two first lines, until you established the time?

##### Share on other sites

@Alex it is known. I listed all the things I know in the first post.

Are you sure? Cause:

velocity = shoot direction * speed

You are asking how can you find shoot direction. Then how can velocity be known?

1. 1
2. 2
Rutin
23
3. 3
4. 4
frob
16
5. 5

• 9
• 33
• 13
• 12
• 10
• ### Forum Statistics

• Total Topics
632579
• Total Posts
3007171

×