2
\$\begingroup\$

I'm working on a project in LibGDX. It's a 2d platform game; you can say it's like Super Mario.

So this is how I move my player to the right:

if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
    player.b2body.applyLinearImpulse(
               new Vector2(0.1f, 0), 
               player.b2body.getWorldCenter(),
               true);
}

When I release the key, the player is still moving a bit. (It still has a "Linear Impulse" force on its physical body, I think).

How can I make it stop?

My question could be simple as: What is the best way to move a physical body on LibGDX in one direction while holding a key. When I release the key, the body stops immediately.

I have tried with "setTransform" and it's causing issues when the body is touching other objects - plus the shape comes "before" the rest of the game in the screen (you can see it on debug)

Thanks.

\$\endgroup\$
  • \$\begingroup\$ This is related to Newton's First Law: a body in motion tends to continue that motion, unless acted upon by an external force. So it's not enough to stop pushing the object, you also need some force/impulse in the opposite direction (like drag/friction or a braking force) to stop it. \$\endgroup\$ – DMGregory Nov 14 '17 at 23:18
  • \$\begingroup\$ @DMGregory Thanks for the info, How will one implement that within LibGDX? How will I stop the force and let it be natural? When you think about it, The force is kind of look like not natural to the a real force e.g - If you see one running, then stopping in the real world, it will take less time to stop if you compare it to LibGDX's physics world, You can say that the box2d forces is acting like the shape is on ice. It's having less grip on the ground and will cause the force to apply more - unlike asphalt road - but this movement, should be in the AIR too, e.g. while jumping left or right. \$\endgroup\$ – Nimitack Nov 15 '17 at 8:29
1
\$\begingroup\$

You can set linear velocity when you release the movement key. It's as simple as doing body.setLinearVelocity(x, y) then just set the appropriate axis to 0.

Example:

if (Gdx.input.isKeyPressed(Keys.W)) {
    // Move forward
} else if (Gdx.input.isKeyPressed(Keys.S)) {
    // Move backwards
} else {
    // Stop moving in the Y direction
    body.setLinearVelocity(body.getLinearVelocity().x, 0);
}

Modifying your existing code to this should probably fix it:

boolean moveRight = (Gdx.input.isKeyPressed(Input.Keys.RIGHT) || JOYSTICK_RIGHT_PRESSED);
boolean moveLeft = (Gdx.input.isKeyPressed(Input.Keys.LEFT) || JOYSTICK_LEFT_PRESSED);

if (moveRight && player2body.getLinearVelocity().x < 3.00f) {
    player2body.applyLinearImpulse(new Vector2(0.15f, 0), player2body.getWorldCenter(), true);
} else if (moveLeft && player2body.getLinearVelocity().x > -3.00f) {
    player2body.applyLinearImpulse(new Vector2(-0.15f, 0), player2body.getWorldCenter(), true);
} else if (moveRight == moveLeft) {
    player2body.setLinearVelocity(0f, player2body.getLinearVelocity().y);
}

The change is in the last else statement. I changed it to an else if statement that checks if you are either:

  • Not moving right or left
  • Moving both right and left

If any of these two cases are true you should be standing still. The reason your old code did not work is because if the player was moving at max speed (velocity >= 3) or min speed (velocity <= -3) the final else statement would run and stop the player completely.

\$\endgroup\$
  • \$\begingroup\$ When i add 'bodyDef.linearDamping' = 1f; nothing is changed.. what am I doing wrong? please help me. pastebin.com/qSrVYuey \$\endgroup\$ – Nimitack Nov 14 '17 at 22:32
  • \$\begingroup\$ @ROSA try 0f instead, I may have made a mistake. (not sure if you saw my comment the first time) \$\endgroup\$ – Charanor Nov 15 '17 at 0:39
  • \$\begingroup\$ Hey @Charanor Adding bodyDef.linearDamping = 0f; won't make any different, i played with this a bit and when i add bodyDef.linearDamping = 1000f; the player box2d almost won't move at all. it's like the box2d is in space..(in space i mean, the X and Y won't almost move) it's not making any good change.. \$\endgroup\$ – Nimitack Nov 15 '17 at 7:53
  • \$\begingroup\$ @ROSA Hmm i'm probably miss-remembering how Box2D works a bit... Try the first method instead. That should definitely work. \$\endgroup\$ – Charanor Nov 15 '17 at 13:11
  • \$\begingroup\$ i have try like this before, but on this way, the player stops and run, and stop and run: he reach the max velocity then stop and so on \$\endgroup\$ – Nimitack Nov 15 '17 at 13:33

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.