3
\$\begingroup\$

My player sprite glitches when it moves across the screen. I've tried multiplying movements by delta time. I've tried rounding. It seems to do this completely at random. Sometimes I can move it all the way across the screen and its fine, other times it glitches and twitches the entire way.

@Override
public void render(float delta) {
    //update the camera
    camera.update();

    //clear the screen with black
    Gdx.gl.glClearColor(0,0,0,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //update the renderer and render
    renderer.setView(camera);
    renderer.render();

    //update players movement on x-axis and apply gravity and increase x-axis speed if the player is jumping
    if(player.movingLeft)
        player.movement[0] -= Math.round(player.playerSpeed * delta);
    if(player.movingRight)
        player.movement[0] += Math.round(player.playerSpeed * delta);
    if(player.movingUp)
        player.movement[1] += player.playerSpeed * delta;

    //handle jumping
    if(player.isJumping) {
        if(player.jumpCurrentY < player.MAX_JUMP_DURATION) {
            player.momentum = 0;
            player.jumpSpeed++;
            player.movement[1] = player.jumpSpeed;
            if (player.jumpSpeed > 5)
                player.jumpSpeed = 5;
            player.jumpCurrentY++;
        } else if(player.hangTime < player.MAX_HANG_TIME) {
            player.momentum = 0;
            player.hangTime++;
            player.movement[1] = 2.8f;
        } else {
            player.isJumping = false;
            player.jumpCurrentY = 0;
            player.hangTime = 0;
            player.jumpSpeed = 0;
            player.momentum = gravity;
        }
    } else {
        player.jumpCurrentY = 0;
    }

    updateSprite(delta, player, player.movement, collidableTiles);

    //set sprite batch projection matrix and draw to the screen
    game.batch.setProjectionMatrix(camera.combined);
    game.batch.begin();
    player.draw(game.batch);
    game.batch.end();

    //reset player movement
    Arrays.fill(player.movement, 0);

    //increment player momentum by gravity and assign it to the players y-axis movement
    player.momentum += gravity;
    player.movement[1] = player.momentum;
    player.momentum += -1;
    if(player.momentum < -5)
        player.momentum = -5;

    //TEMPORARY
    camera.position.set(Math.round(player.getX()), Math.round(player.getY()), 0);


}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you show us an example of what this glitch looks like? The symptoms are often helpful in identifying the root cause. Without seeing an example, my best guess is it may be due to non-integer scaling. You should also edit your question to include a Minimal Complete Verifiable Example — all the code needed to demonstrate the issue, present inside the question itself, not linked in an external site whose contents may change or go offline. \$\endgroup\$
    – DMGregory
    Commented May 1, 2022 at 3:44
  • 1
    \$\begingroup\$ Usually it's good form to paste only the relevant code, instead of pasting the entire source code for the entire project. \$\endgroup\$ Commented May 1, 2022 at 14:04

1 Answer 1

7
\$\begingroup\$

It happens because you update the camera's position out of sync with the player's position.

In public void render(float delta) in LevelOne you start by updating the camera's transform by calling camera.update, but you really want to do this after you've calculated the new position of the player.

If you change around your code to first calculate the new positions of the player, then call the updateSprite method and then call camera.update the glitching will go away.

Or in code, change your LevelOne render method to:

@Override
public void render(float delta) {

    //clear the screen with black
    Gdx.gl.glClearColor(0,0,0,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);


    //update players movement on x-axis and apply gravity and increase x-axis speed if the player is jumping
    if(player.movingLeft)
        player.movement[0] -= Math.round(player.playerSpeed * delta);
    if(player.movingRight)
        player.movement[0] += Math.round(player.playerSpeed * delta);
    if(player.movingUp)
        player.movement[1] += player.playerSpeed * delta;

    //handle jumping
    if(player.isJumping) {
        if(player.jumpCurrentY < player.MAX_JUMP_DURATION) {
            player.momentum = 0;
            player.jumpSpeed++;
            player.movement[1] = player.jumpSpeed;
            if (player.jumpSpeed > 5)
                player.jumpSpeed = 5;
            player.jumpCurrentY++;
        } else if(player.hangTime < player.MAX_HANG_TIME) {
            player.momentum = 0;
            player.hangTime++;
            player.movement[1] = 2.8f;
        } else {
            player.isJumping = false;
            player.jumpCurrentY = 0;
            player.hangTime = 0;
            player.jumpSpeed = 0;
            player.momentum = gravity;
        }
    } else {
        player.jumpCurrentY = 0;
    }


    updateSprite(delta, player, player.movement, collidableTiles);
    //TEMPORARY
    camera.position.set(Math.round(player.getX()), Math.round(player.getY()), 0);
    //update the camera
    camera.update();


    //update the renderer and render
    renderer.setView(camera);
    renderer.render();


    //set sprite batch projection matrix and draw to the screen
    game.batch.setProjectionMatrix(camera.combined);
    game.batch.begin();
    player.draw(game.batch);
    game.batch.end();

    //reset player movement
    Arrays.fill(player.movement, 0);

    //increment player momentum by gravity and assign it to the players y-axis movement
    player.momentum += gravity;
    player.movement[1] = player.momentum;
    player.momentum += -1;
    if(player.momentum < -5)
        player.momentum = -5;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This worked!! Thank you for helping!! \$\endgroup\$
    – DawnShard
    Commented May 1, 2022 at 15:02
  • 1
    \$\begingroup\$ Glad it helped, @DawnShard. It is sometimes helpful to think of the gameloop as something that does two distinct things; update the state (positions) and render. Usually it is easier to keep those separate so that they don't overlap. \$\endgroup\$
    – bornander
    Commented May 2, 2022 at 5:54

You must log in to answer this question.

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