Reputation: 5
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;
}
}
Upvotes: 0
Views: 1030
Reputation: 9783
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 renderer
s 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.
Upvotes: 1