Libgdx zoom and pan map

This time I’m on a surprising problem and after some work I’m here to ask for help. ???

My point is to develop a “simple” way to have a decent zoom and pan functionality for a turn based game. In my mind requirement is to realize a zoom camera on top of a map, something like


take a look to zoom in/out an pan.

Now, after some work I have to admit I don’t have find a tutorial/documentation on how to organize my codebase to solve this problem, so the following points are my thoughts on this topic so far:

  1. in my init code:
  • create a new OrthographicCamera: it’s a 2d game, I don’t need anything else
  • create a new Stage with some actors in (for example a window or a button)
  • use a InputMultiplexer and add two InputProcessor: one for stage (UI) and one for game entities: so I can separate input on ui and on game entities
  1. in my render code every frame:
  • clear everything :smiley:
  • update camera
  • batch.begin
  • draw the baseMap
  • batch.end
  • stage.act: update ui
  • stage.draw: render ui
  1. when zoom change, only camera zoom change, so ui is not scaled (this is good of course!)

package test;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;

public class MapPanZoomExample extends ApplicationAdapter {

	private OrthographicCamera cam;
	private Image map;
	public SpriteBatch batch;
	private Stage stage;
	private Skin skin;

	public void create() {
		batch = new SpriteBatch();
		// create ui
		stage = new Stage();
		skin = new Skin(Gdx.files.internal("defaultSkin/uiskin.json"));
		final Dialog dialog = new Dialog("Welcome", skin, "dialog") {
			public void result(Object obj) {
				System.out.println("Closed dialog!");
		dialog.setPosition( / 2, / 2, 0);
		dialog.text("Hello World ! Try to move with mouse and zoom with mouse wheel");
		dialog.button("Close", true); // sends "true" as the result
		// init camera
		cam = new OrthographicCamera(,;
		// init map image
		map = new Image(new Texture("exampleMap.jpg"));
		// init input processor
		InputMultiplexer multi = new InputMultiplexer();
		multi.addProcessor(new InputProcessor() {

			public boolean touchUp(int screenX, int screenY, int pointer, int button) {
				return false;

			public boolean touchDragged(int screenX, int screenY, int pointer) {
				return false;

			public boolean touchDown(int screenX, int screenY, int pointer, int button) {
				System.out.println("clicked: " + screenX + "," + screenY);
				return false;

			public boolean scrolled(int amount) {
				// arbitrary max zoomIn and max zoomOut values here
				if (cam.zoom - amount >= -0.25f && cam.zoom - amount <= 2) {
					cam.zoom -= (float) amount / 10f;
				return true;

			public boolean mouseMoved(int screenX, int screenY) {
				return false;

			public boolean keyUp(int keycode) {
				return false;

			public boolean keyTyped(char character) {
				return false;

			public boolean keyDown(int keycode) {
				System.out.println("Key down: " + keycode);
				int step = 20;
				int dx = 0;
				int dy = 0;
				if (keycode == Keys.LEFT) {
					dx = -step;
				if (keycode == Keys.RIGHT) {
					dx = step;
				if (keycode == Keys.UP) {
					dy = step;
				if (keycode == Keys.DOWN) {
					dy = -step;
				cam.translate(dx, dy);
				return true;


	public void render() {;
		map.draw(batch, 1);

	public static void main(String[] arg) {
		LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
		config.width = 1024;
		config.height = 768;
		new LwjglApplication(new MapPanZoomExample(), config);



  1. zoom works fine, but how to translate/scale coordinates on screen when map is scaled ?
  2. why If user try to move the map using keyboard, nothing moves ? see row 96 - 112
  3. how to implement to move the map when mouse is “near” borders ?
  4. order in render() method is fine ? see row 122

thanks in advance!

question #1: you can use Camera.unproject() to change mouse screen coordinates into game world coordinates, which accounts for the zoom and translation.

okay, thanks! Bu why translate does not work ?

Yay, one of the rare times I can help.

You are missing a camera.position.set() call…