Advertisement

Efficiently detect shoot direction with gravity playing a role?

Started by March 05, 2016 04:40 PM
16 comments, last by L. Spiro 8 years, 8 months ago

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)

7Afw7nR.png

Game I'm making - GANGFORT, Google Play, iTunes

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.

Advertisement

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?

Game I'm making - GANGFORT, Google Play, iTunes


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)

?

You have a system of 5 equations and 5 unknowns:

EKbfFX3.png

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?

@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?

Game I'm making - GANGFORT, Google Play, iTunes

Advertisement

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

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

Game I'm making - GANGFORT, Google Play, iTunes

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?

@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?

This topic is closed to new replies.

Advertisement