I've tried searching all over for the solution to this problem and have had no luck; although I have tried various suggestions which I will detail below along with the issue.
I've created a very small and simple sample project to test rendering a Tiled map and setting up a camera with a viewport and some simple input handling so I can "pan" around the map with WASD. The problem is that when I try to pan around the map, I get weird effects with the map. These include:
The things I have tried:
Does any one have any ideas of what could be going wrong? I just wan't to make sure I understand how to render the map and move the camera properly without any issues before continuing.
Exact Code:
public class GameScreen implements Screen {
final Alpha game;
private OrthographicCamera camera;
private FitViewport viewport;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private Rectangle player;
public GameScreen(final Alpha game) {
this.game = game;
camera = new OrthographicCamera();
viewport = new FitViewport(800, 480, camera);
TmxMapLoader.Parameters params = new TmxMapLoader.Parameters();
params.textureMinFilter = Texture.TextureFilter.Nearest;
params.textureMagFilter = Texture.TextureFilter.Linear;
map = new TmxMapLoader().load("simple_padded_same_color.tmx");
renderer = new OrthogonalTiledMapRenderer(map);
player = new Rectangle(32,32,32,32);
}
@Override
public void render(float delta) {
camera.update();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// handle input
if (Gdx.input.isKeyPressed(Input.Keys.A)) {
player.setX(player.getX() - 200 * delta);
}
if (Gdx.input.isKeyPressed(Input.Keys.D)) {
player.setX(player.getX() + 200 * delta);
}
if (Gdx.input.isKeyPressed(Input.Keys.W)) {
player.setY(player.getY() + 200 * delta);
}
if (Gdx.input.isKeyPressed(Input.Keys.S)) {
player.setY(player.getY() - 200 * delta);
}
camera.position.set(player.getX(), player.getY(), 0);
renderer.setView(camera);
renderer.render();
}
@Override
public void resize(int width, int height) {
viewport.update(width, height);
}
@Override
public void show() {
}
@Override
public void hide() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
map.dispose();
renderer.dispose();
}
}
Here is what your render function should look like
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// force a constant delta
float gameDelta = 0.1f;
// handle input
if (Gdx.input.isKeyPressed(Input.Keys.A)) {
player.setX(player.getX() - 200 * gameDelta);
}
if (Gdx.input.isKeyPressed(Input.Keys.D)) {
player.setX(player.getX() + 200 * gameDelta);
}
if (Gdx.input.isKeyPressed(Input.Keys.W)) {
player.setY(player.getY() + 200 * gameDelta);
}
if (Gdx.input.isKeyPressed(Input.Keys.S)) {
player.setY(player.getY() - 200 * gameDelta);
}
// set camera position first
camera.position.set(player.getX(), player.getY(), 0);
// update camera
camera.update();
// then set the view
renderer.setView(camera);
// last render
renderer.render();
}
First, you will need to update your camera after setting the new position. Then, try to use a constant delta instead of the actual one which will lead to weird camera movement as the libgdx delta represents the amount of time between two frames and is not constant. This should remove the wavy effect you have in your game.
To understand your delta issue, I recommend reading this article http://gameprogrammingpatterns.com/game-loop.html
Ideally you would use an Entity System framework and a specific PhysicSystem and a MotionSystem to compute your player movement and decouple the player position computation from the rendering loop.
Libgdx comes with Ashley, you can also have a look at Artemis-odb which is a also great project and more complete than Ashley in my opinion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With