0
votes

I am developing a libgdx rpg desktop game similar to the style of pokemon (top down view). In the game I use a OrthographicCamera to follow the player as he walks around a Tmx map created using Tiled. The problem that I am having is that when the player moves among the map, the player eventually out runs the camera, having him run off the screen opposed to him staying centered. I've searched Google and YouTube having found nothing that solves the problem.

WorldRenderer.class

public class WorldRenderer {

private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
public OrthographicCamera camera;
private Player player;

TiledMapTileLayer layer;


public WorldRenderer() {
    map = new TmxMapLoader().load("maps/testMap2.tmx");
    renderer = new OrthogonalTiledMapRenderer(map);

    player = new Player();
    camera = new OrthographicCamera();
    camera.viewportWidth = Gdx.graphics.getWidth()/2;
    camera.viewportHeight = Gdx.graphics.getHeight()/2;
}
public void render (float delta) {
    camera.position.set(player.getX() + player.getWidth() / 2, player.getY() + player.getHeight() / 2, 0);
    camera.update();
    renderer.setView(camera);
    renderer.render();
    player.render(delta);
}
}   

Player.class

public class Player {

public Vector2 position; 
private float moveSpeed;
private SpriteBatch batch;

//animation
public Animation an;
private Texture tex;
private TextureRegion currentFrame;
private TextureRegion[][] frames;
private float frameTime;

public Player(){
    position = new Vector2(100, 100);
    moveSpeed = 2f;
    batch = new SpriteBatch();
    createPlayer();
}

public void createPlayer(){
    tex = new Texture("Sprites/image.png");
    frames = TextureRegion.split(tex, tex.getWidth()/3, tex.getHeight()/4);
    an = new Animation(0.10f, frames[0]);
}

public void render(float delta){
    handleInput();

    frameTime += delta;
    currentFrame = an.getKeyFrame(frameTime, true);

    batch.begin();
    batch.draw(currentFrame, position.x, position.y, 50, 50);
    batch.end();
}

public void handleInput(){
    if(Gdx.input.isKeyPressed(Keys.UP)){
        an = new Animation(0.10f, frames[3]);
        position.y += moveSpeed;
    }
    if(Gdx.input.isKeyPressed(Keys.DOWN)){
        an = new Animation(0.10f, frames[0]);
        position.y -= moveSpeed;
    }
    if(Gdx.input.isKeyPressed(Keys.LEFT)){
        an = new Animation(0.10f, frames[1]);
        position.x -= moveSpeed;
    }
    if(Gdx.input.isKeyPressed(Keys.RIGHT)){
        an = new Animation(0.10f, frames[2]);
        position.x += moveSpeed;    
    }
    if(!Gdx.input.isKeyPressed(Keys.ANY_KEY)){
        an = new Animation(0.10f, frames[0]);
    }
}

public void dispose(){
    batch.dispose();
}

public float getX(){
    return position.x;
}

public float getY(){
    return position.y;
}

public int getWidth(){
    return 32;
}

public int getHeight(){
    return 32;
}

}
1
camera.setposition(player.getx,player.gety,0) don't add half of the screen and heightBoldijar Paul
@BoldijarPaul he adds player.getWidth() / 2 and player.getHeight() / 2.Robert P
@Springrbua ah my bad, sorryBoldijar Paul

1 Answers

1
votes

The problem is the following:

player.render(delta);

Which uses the SpriteBatch created in the Player class.
This SpriteBatch does not use the Matrix of the Camera and therefore it always showes the same part of the world, where the Player runs out of the screen.
There are now 2 posibilities:
Use spriteBatch.SetProjectionMatrix(camera.combined). For this you need to store a reference to the camera inside the Player class.
Or use a much cleaner solution: Separate the logic and the view. Use one class for drawing the map and the player.
So in the WorldRenderer instead of calling player.render() you should draw the player there. You could use the renderers SpriteBatch for drawing (renderer.getSpriteBatch() should work). I guess that this SpriteBatch allready uses the camera.combined Matrix so you don't need to care about this.

Hope it helps.