[libgdx] Questions About Cameras

Hey,

I’ve finally managed to get a tiled map loaded using libgdx and after a little bit of guess-work I figured out how to move around the map using keys. I’m not sure what to look up to answer these questions so I’ll ask them here.

Now for the questions…

Why is it that the code below zooms in on the map when I remove the “(w/h) *” from the X value and then zooms out when I put it back?

float w = Gdx.graphics.getWidth();
		float h = Gdx.graphics.getHeight();

		camera = new OrthographicCamera();
		camera.setToOrtho(false, (w/h) * cameraX, cameraY);
		camera.update();

When I stretch (re-size) the window the map becomes zoomed in instead of just showing more of the map. How would I fix this? I’ll post the code I’m using at the bottom.

When moving around with the arrow keys/WASD the view moves at an extremely fast speed. The only way to fix this, that I can think of, was to change the values of cameraX and cameraY to doubles and instead of increasing/decreasing by 1 when the key is pressed, I would increase/decrease by a decimal value. This, probably, would have worked but the method “setToOrtho” doesn’t allow double values. Is there another way to adjust the speed that you move around the map?

Here is my hacked-together code:

package screens;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;

public class Screen_Game2 implements ApplicationListener {

	private TiledMap map;
	private TiledMapRenderer renderer;
	private OrthographicCamera camera;
	private int cameraX = 10, cameraY = 10;
	private BitmapFont font;
	private SpriteBatch batch;

	@Override
	public void create() 
	{		
		float w = Gdx.graphics.getWidth();
		float h = Gdx.graphics.getHeight();

		camera = new OrthographicCamera();
		camera.setToOrtho(false, (w/h) * cameraX, cameraY);
		camera.update();

		font = new BitmapFont();
		batch = new SpriteBatch();

		map = new TmxMapLoader().load("assets/Maps/Map_01.tmx");
		renderer = new OrthogonalTiledMapRenderer(map, 1f / 32f);
	}

	@Override
	public void render() 
	{
		Gdx.gl.glClearColor(0.55f, 0.55f, 0.55f, 1f);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		
		float w = Gdx.graphics.getWidth();
		float h = Gdx.graphics.getHeight();
		if(Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A))
		{
			cameraX -= 1;
			camera.position.x = (w/h) * cameraX;
		}
		if(Gdx.input.isKeyPressed(Keys.RIGHT) || Gdx.input.isKeyPressed(Keys.D))
		{
			cameraX += 1;
			camera.position.x = (w/h) * cameraX;
		}
		if(Gdx.input.isKeyPressed(Keys.UP) || Gdx.input.isKeyPressed(Keys.W))
		{
			cameraY += 1;
			camera.position.y = cameraY;
		}
		if(Gdx.input.isKeyPressed(Keys.DOWN) || Gdx.input.isKeyPressed(Keys.S))
		{
			cameraY -= 1;
			camera.position.y = cameraY;
		}
		
		camera.update();
		renderer.setView(camera);
		renderer.render();
		batch.begin();
		font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 10, 20); 
		batch.end();
	}

	@Override
	public void dispose () {
		map.dispose();
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resize(int arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
		
	}
}

Thanks in advance for any answers!

The map will obviously zoom in if (w/h) results in a number less than 1 (ie, if w<h) because the projection width (x) is decreased. Removing it logically zooms it out.
Reading the rest of your post, constantly setting the camera to different ortho values isn’t the correct way to do it. You should be adjusting the position vector of the camera object.
E.g.


if(Gdx.input.isKeyPressed(Keys.W){
camera.position.y++;
}

No need to keep a separate cameraY variable. Also, try adding


camera.update();

to your render loop.

Thanks, the map now looks properly instead of stretched. It still zooms in when you re-size the window but as long as it’s scaling properly, which it is now, it should be fine. I also just noticed that there is a camera.position.z so I can probably set the map to be zoom-able later on.

The only thing that I still need to figure out is how to make the view move slowly instead of fast. I’m currently able to scroll over the whole test map within 5 seconds when it should take 10-20 seconds.

While typing this I figured out that camera.position. can be set to double values; this solved the issue with not being able to scroll slowly.

Thanks again!