0
votes

I am trying to make a simple platformer, and when the player jumps I set the velocity to some constant, and then decrease that constant over time by gravity * deltaTime. However, for some reason this is resulting in varying jump height. I think it has to do with the deltaTime because when I replace deltaTime with a constant in the main game loop this issue goes away.

Here is the revelvent code.

GameState

public void resolveInput(float deltaTime) {
    if(Gdx.input.isKeyJustPressed(Keys.ESCAPE))
        Gdx.app.exit(); //temporary until we build menus

    player.velocity.x = 0;
    if(Gdx.input.isKeyPressed(Keys.A)) {
        player.velocity.x -= Constants.PLAYER_MOVE_SPEED * deltaTime;
        player.right = false;
    }
    if(Gdx.input.isKeyPressed(Keys.D)) {
        player.velocity.x += Constants.PLAYER_MOVE_SPEED * deltaTime;
        player.right = true;
    }
    if(Gdx.input.isKeyPressed(Keys.SPACE) && !player.falling) {
        player.velocity.y = Constants.PLAYER_JUMP_SPEED;
        player.falling = true;
    }

}
public void update(float deltaTime) {
    resolveInput(deltaTime);
    world.update(deltaTime);

    camHelper.update(deltaTime);
}

World:

public void update(float deltaTime) {
    player.update(deltaTime);

    player.setPosition(resolveCollisions());
}

public Vector2 resolveCollisions() {
    Rectangle p = player.getBoundingRectangle();

    //The rest of the code doesn't get called in my test cases so I won't put it in here...

    return new Vector2(p.x + player.velocity.x, p.y + player.velocity.y);

}//resolveCollisions

Player:

public void update(float deltaTime) {
    if(velocity.len() == 0)
        sTime = 0;
    else
        sTime += deltaTime;
    if(falling)
        velocity.y -= Constants.GRAVITY * deltaTime;
    velocity.y = MathUtils.clamp(velocity.y, -Constants.PLAYER_MAX_SPEED, Constants.PLAYER_MAX_SPEED);
}

Any help would be much appreciated: a platformer doesn't work well if the player doesn't always jump the same height!

3

3 Answers

0
votes

The jump height is obviously varying because of the deltaTime. The deltaTime is the time in between each frame, and this time varies from frame to frame. That's why, if you multiply it by a number that is constantly different, the jump height will always be different.

You can fix this by just making your velocity.y always be the same.

Just do something like, whenever the user jumps, make the velocity.y equal a certain constant, then make the gravity detract from it each frame (the gravity can be multiplied by the deltaTime btw).

public static final int GRAVITY = -15;

public void onJump(){
    velocity.y = 300;
}

public void update(float deltaTime){
    velocity.add(0, GRAVITY * deltaTime); //make the gravity detract from the upwards velocity each frame
}
0
votes

How about declaring a new variable firstY and a new value JUMP_HEIGHT?

GameState:

if(Gdx.input.isKeyPressed(Keys.SPACE) && !player.falling) {
   player.firstY = player.getBoundingRectangle().y;
   player.velocity.y = Constants.PLAYER_JUMP_SPEED;
   player.falling = true;
}  

World:

public Vector2 resolveCollisions() {
   Rectangle p = player.getBoundingRectangle();
   //JUMP_HEIGHT is a height player always jumps
   if(p.y + player.velocity.y >= player.firstY + Constants.JUMP_HEIGHT) {
     player.velocity.y = 0;
     return new Vector2(p.x + player.velocity.x, player.firstY + JUMP_HEIGHT);
   }
   return new Vector2(p.x + player.velocity.x, p.y + player.velocity.y);
}

I hope this will help you.

0
votes

For whatever reason, this morning the issue resolved itself. This makes me nervous because it could still happen again later, but for now it's a non-issue. Thank you all for the good ideas!

EDIT After having worked on this much more, I can say whenever I have a Skype call going on in the background this issue happens, but at no other time.