TJRC
TJRC

Reputation: 434

How do I get my camera to update the same frame as my player sprite?

In LibGDX I'm trying to have my OrthographicCamera follow the playersprite when I move it around. Currently, the playersprite gets updated first and then in the next frame the camera updates to the position of the playersprite in the previous frame. Here is an example: https://i.imgur.com/wxJUizU.gifv

I have tried moving gameMap.render(cam) to the bottom of the method, but not only does it not solve my problem, it also places the map textures above the playersprite, so you won't be able to see the playersprite anymore when it moves under the map.

Here is the code for rendering the playersprite and camera:

public void render () {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    cam.viewportHeight = Gdx.graphics.getHeight() / 3;
    cam.viewportWidth = Gdx.graphics.getWidth() / 3;

    gameMap.render(cam);

    gameMap.getTiledMapRenderer().getBatch().begin();
    player.draw(gameMap.getTiledMapRenderer().getBatch());
    gameMap.getTiledMapRenderer().getBatch().end();

    cam.position.x = player.getX() + (player.getWidth() / 2);
    cam.position.y = player.getY() + (player.getHeight() / 2);
    cam.update();
}

Upvotes: 0

Views: 132

Answers (2)

Morchul
Morchul

Reputation: 2037

Like Bradley says you should split your logic into two parts: update and render

Create a udpate() method where you place all your things to update and call this method first in the render() method:

public void update(){
    //Update camera position
    cam.position.x = player.getX() + (player.getWidth() / 2);
    cam.position.y = player.getY() + (player.getHeight() / 2);
    //apply all updates to the camera before this the changed position won't apply to the camera
    cam.update();
}

@Override
public void render() {
    //First call the update method we created
    update();

    //Clear the Screen
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //Render
    gameMap.render(cam);

    gameMap.getTiledMapRenderer().getBatch().begin();
    player.draw(gameMap.getTiledMapRenderer().getBatch());
    gameMap.getTiledMapRenderer().getBatch().end();
}

You don't need to call:

cam.viewportHeight = Gdx.graphics.getHeight() / 3;
cam.viewportWidth = Gdx.graphics.getWidth() / 3;

every frame. It's enough to call it ones in the create() method

Upvotes: 0

Bradley Boutcher
Bradley Boutcher

Reputation: 21

Typically, you want to break your logic into two sections:

  • Update

  • Render

So, before each frame you want to perform any pertinent calculations. Your camera is currently updating late, because it isn't performing logic until after the gameMap has been updated. For example:

// Perform logic and update the state
public void Update () {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    cam.viewportHeight = Gdx.graphics.getHeight() / 3;
    cam.viewportWidth = Gdx.graphics.getWidth() / 3;

    gameMap.getTiledMapRenderer().getBatch().begin();

    cam.position.x = player.getX() + (player.getWidth() / 2);
    cam.position.y = player.getY() + (player.getHeight() / 2);
}

// Draw map
public void Render () {
    gameMap.render(cam);

    player.draw(gameMap.getTiledMapRenderer().getBatch());
    gameMap.getTiledMapRenderer().getBatch().end();

    cam.update();
}

I'm not familiar with the framework you're using, so I can't tell if this would run or not, but when working with frames in any game development situation, this is how you want to handle things.

Upvotes: 1

Related Questions