How to keep the same jump height in libgdx

2019-07-20 19:08发布

问题:

I'm developing a 2D video game using libgdx. I ran into a problem when I try to make jumping a body. It does not jump as expected after making it moving to the right.(I can only move to the right or Jump)

If the body jumps before it's moving to the right everything goes fine. But If I decide to make jumping the body after moving it to the right. The body no longer jumps to the same height (It jumps less high). And I don't figure out why..

My method to jump the body :

    if (player.isPlayerOnGround()) {
        body.applyForceToCenter(0, 200, true);
    }

My method to move the body right

    if (player.isPlayerOnGround()) {
        body.setLinearDamping(0f);
        body.setLinearVelocity(1f,0f);
        isMoving = true;
    }

My method to stop the body moving right :

    body.setLinearDamping(5f);
    isMoving = false;

The world use a -9.81f gravity and the body 1f for the Mass.

P.S : Sorry for me bad english, it's not my native language.

Thank you.

回答1:

First thing: never use forces to jump. Force has different effects based on how long that force acted. Second: don't use linearDamping. It makes your physics floaty and not real. You could use impulse instead of force in jumping method (it doesn't work very well actually). I'm using this method and it works perfectly

    public void jump() {
        if (jumpDelta >= Constants.PLAYER_JUMP_RATE) {
            grounded = level.getContactListener().numFootContacts > 0;
            if (grounded) {
                body.setLinearVelocity(body.getLinearVelocity().x, 7);
                jumpDelta = 0;
            }
        }
    }

Where if (jumpDelta >= Constants.PLAYER_JUMP_RATE) prevents from too fast jumping (like two or more jumps at once), grounded = level.getContactListener().numFootContacts > 0; checks if player is on platform and finally this body.setLinearVelocity(body.getLinearVelocity().x, 7); changes body's vertical velocity. Changing velocity works better than applying impulse because impulse doesn't set velocity, it increases velocity. So if player was moving down with vertical velocity -3 m/s then its velocity will become 4, not 7 as we wanted.

P.S. Instead of linear damping i use this method

    public void stopMoving() {
        if (grounded) {
            if (Math.abs(body.getLinearVelocity().x) <= 0.5f)
                body.setLinearVelocity(0, body.getLinearVelocity().y);
            else
                body.applyLinearImpulse(-direction * 0.5f, 0,
                        body.getPosition().x, body.getPosition().y, true);
        } else if (Math.abs(body.getLinearVelocity().x) <= 0.1f)
            body.setLinearVelocity(0, body.getLinearVelocity().y);
        else
            body.applyLinearImpulse(-direction * 0.1f, 0, body.getPosition().x,
                    body.getPosition().y, true);
    }

This method can seem too complex but it's really simple. First part handles body's movement on ground and second in the air. if-statements prevent from changing body's direction while stopping and direction variable can be 1 if body's moving right, -1 if body's moving left and 0 if body isn't moving.