3
\$\begingroup\$

I'm developing a simple 3D ship game using libgdx and bullet.

When a user taps the mouse I create a new shell object and send it in the direction of the mouse click. However, if the user has tapped the mouse in the direction where the ship is currently moving, the ship catches up to the shells very quickly and can sometimes even get hit by them - simply because the speed of shells and the ship are quite comparable.

I think I need to account for ship speed when generating the initial impulse for the shells, and I tried doing that (see "new line added"), but I cannot figure out if what I'm doing is the proper way and if yes, how to calculate the correct coefficient.

public void createShell(Vector3 origin, Vector3 direction, Vector3 platformVelocity, float velocity) {
    long shellId = System.currentTimeMillis(); // hack
    ShellState state = getState().createShellState(shellId, origin.x, origin.y, origin.z);
    ShellEntity entity = EntityFactory.getInstance().createShellEntity(shellId, state);

    add(entity);
    entity.getBody().applyCentralImpulse(platformVelocity.mul(velocity * 0.02f)); // new line added, to compensate for the moving platform, no idea how to calculate proper coefficient
    entity.getBody().applyCentralImpulse(direction.nor().mul(velocity));
}

private final Vector3 v3 = new Vector3();
public void shootGun(Vector3 direction) {
    Vector3 shipVelocity = world.getShipEntities().get(id).getBody().getLinearVelocity();
    world.getState().getShipStates().get(id).transform.getTranslation(v3); // current location of our ship
    v3.add(direction.nor().mul(10.0f)); // hack; this is to avoid shell immediately impacting the ship that it got shot out from  
    world.createShell(v3, direction, shipVelocity, 500);
}

Edit - I switched to:

    v3.set(direction);
    v3.nor().mul(velocity);

    if (platformVelocity != null)
        v3.add(platformVelocity);

    entity.getBody().setLinearVelocity(v3);

And it seems to work (so adding the velocities and setting them on the body).

However, I'm not sure what the drawbacks are and why the tutorial application used impulses instead of setting velocities.

I also think that while this is physically correct it leads to strange results (gun range is two times further when shooting forward than when shooting sideways).

The root cause is because really the shells are indeed too slow, but I like them slow as otherwise the gameplay is too fast-paced, and they travel too far.

I think I need some compromise between physics-realistic and ignore-platform-velocity.

\$\endgroup\$
1
  • \$\begingroup\$ What I feel from reading this is that either the ship is too fast or your bullet is too slow. You could account for the velocity of the ship when firing bullets, but does that mean the bullets will have slower velocity when shot in a direction opposite to the ship's movement? \$\endgroup\$ Nov 28, 2012 at 15:24

2 Answers 2

6
\$\begingroup\$

The shell's speed was the same as the ship's speed before it got fired, if you think about it. It was sitting on the ship. So, if you add the velocity from being fired to the velocity of the ship, you should get the correct result.

\$\endgroup\$
9
  • \$\begingroup\$ I still feel his bullet is too slow or his ship is too fast. If he feels that his ship catches up with the bullet, if he bullet is fired against the direction of motion, adding the ship's velocity will either make the bullet stand-still or move in the direction of ship (and may even hit it :O). \$\endgroup\$ Nov 28, 2012 at 15:28
  • 3
    \$\begingroup\$ That doesn't make conservation of momentum the wrong thing to do, it just means his ship's gun is embarassingly ineffective. Maybe the sailors should consider using a little more gun powder. If the bullet catches up with the ship when fired AGAINST the direction of motion, that means the ship is either slowing down incredibly fast, or the bullet was fired with negative velocity. In the first case, the boys in the engine room are really working hard! Maybe too hard. In the second case, I'd say that gun needs serious repairs. \$\endgroup\$
    – Eric B
    Nov 28, 2012 at 15:29
  • \$\begingroup\$ LOL, or programmatically, the Bullet-to-Ship velocity ratio should be higher than what it is. \$\endgroup\$ Nov 28, 2012 at 15:34
  • 3
    \$\begingroup\$ From a gameplay perspective, conservation of momentum may very well be wrong. So few games use it that it can (and often does) feel wrong in games that use it. Whether that holds true for this particular genre of game, I don't know. But in general, do what's fun, not what's most realistic. \$\endgroup\$ Nov 28, 2012 at 17:31
  • 1
    \$\begingroup\$ Tribes conserves momentum, making it incredibly hard to hit targets, which is exactly why some players LIKE it. \$\endgroup\$
    – Eric B
    Nov 28, 2012 at 19:36
4
\$\begingroup\$

Replace your new line with:

entity.getBody().setLinearVelocity(platformVelocity);

You might want to do the same for the shell also instead of finding desired impulse, which depends on the mass of the shell.

\$\endgroup\$
2
  • \$\begingroup\$ Good point, I guess don't need to use impulses (though not sure if that approach has drawbacks). But if I would want to find the impulse, how do I calculate it? \$\endgroup\$
    – John M
    Nov 28, 2012 at 18:45
  • 1
    \$\begingroup\$ @JohnMurdoch: Multiply the desired velocity change by the mass of the projectile to get the needed impulse. But that's kind of silly, since the physics engine will just divide the impulse by the mass to get the velocity change again. \$\endgroup\$ Nov 29, 2012 at 2:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .