3
\$\begingroup\$

I am trying to both A.) Pinch zoom my game scene and B.) Move (scroll) my game scene but I have not found many examples. I learn more by examples than by reading API documentation (although I am willing to resort to that if there is no other way) and the lack of examples has put a damper on my game.

How do I do these things?

A little background:

I am developing a RPG for Android and one of the features in my game is the ability to purchase a game map for money that let's users see the location of enemies in the level and all of the obstacles. Since most Android devices are quite small 3.5" to 5" I thought it would be a good idea to let the user zoom into the map and then scroll around. I have omitted most of my game code.

Relevant code

I have

 //Irrelevant code omitted for clarity and in accordance with the help center
    public class MyGdxGame implements ApplicationListener
    {
Texture mapTexture;
SpriteBatch batch;

@Override
public void create(){
    mapTexture = new Texture(Gdx.files.internal("map.png"));
    batch = new SpriteBatch();
}

@Override
public void render(){
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.glClear(GL20_GL_COLOR_BUFFER_BIT);
    batch.begin();
    batch.draw(0 , 0, Gdx.graphics.getWidth, Gdx.graphics.getHeight());
    batch.end();
}

@Override
public void dispose(){
}

//I want to zoom in to the map here
@Override
public void resize(int width, int height){
}

@Override
public void pause(){
}

@Override
public void resume(){
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Here is the code that I used in my strategy game for zoom,pinch etc..

For handling the camera and setting the screen resolution based on the aspect ratio we have:

aspectRatio = (float)Gdx.graphics.getHeight() / (float)Gdx.graphics.getWidth();
height = width * aspectRatio;
camera = new OrthographicCamera(width,height);

camera.position.set(width / 2, height / 2, 0);
camera.viewportWidth = width / 2;
camera.viewportHeight = height / 2;
camera.update();

handleInput() function calls all the input events on keyboard and process them rest of inputs like pinch and zoom will be handled by implementation GestureDetector

To clamp the camera with in bounds we have:

 camera.position.x = MathUtils.clamp( camera.position.x, effectiveViewportWidth / 2f, width - effectiveViewportWidth / 2f);
 camera.position.y = MathUtils.clamp(camera.position.y, effectiveViewportHeight / 2f, height- effectiveViewportHeight / 2f);

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

public class ScreenExample implements Screen, GestureListener {
    private SpriteBatch batch;
    private Texture texture;
    public OrthographicCamera camera;
    float elapsedTime = 0;
    float zoomFactor = (float) 0;
    Vector3 touchPosition;
    float width = 800, height, aspectRatio;

    public ScreenExample() {
        aspectRatio = (float) Gdx.graphics.getHeight() / (float) Gdx.graphics.getWidth();
        height = width * aspectRatio;
        camera = new OrthographicCamera(width, height);
        camera.position.set(width / 2, height / 2, 0);
        camera.viewportWidth = width / 2;
        camera.viewportHeight = height / 2;
        camera.update();


        texture = new Texture(Gdx.files.internal("background.png"));


    }

    @Override
    public void show() {

        camera.zoom = 2;

        touchPosition = new Vector3();

        Gdx.input.setInputProcessor(new GestureDetector(this));

    }

    @Override
    public void render(float delta) {
        handleInput();
        camera.update();


        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.setProjectionMatrix(camera.combined);

        batch.begin();
        batch.draw(texture, 0, 0, width, height);

        batch.end();


    }


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

    @Override
    public void resize(int width, int height) {


    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public boolean touchDown(float x, float y, int pointer, int button) {
// TODO Auto-generated method stub
        touchPosition.set(x, y, 0);
        camera.unproject(touchPosition);

        return false;
    }

    @Override
    public boolean tap(float x, float y, int count, int button) {
// TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean longPress(float x, float y) {
// TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean fling(float velocityX, float velocityY, int button) {
// TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean pan(float x, float y, float deltaX, float deltaY) {
        // TODO Auto-generated method stub

        camera.translate(-deltaX, deltaY);


        return false;
    }

    private void handleInput() {
        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            camera.zoom += 0.02;
        }
        if (Gdx.input.isKeyPressed(Input.Keys.Q)) {
            camera.zoom -= 0.02;
        }
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            camera.translate(-3, 0, 0);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            camera.translate(3, 0, 0);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
            camera.translate(0, -3, 0);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
            camera.translate(0, 3, 0);
        }
        int rotationSpeed = 1;
        if (Gdx.input.isKeyPressed(Input.Keys.W)) {
            camera.rotate(-rotationSpeed, 0, 0, 1);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.E)) {
            camera.rotate(rotationSpeed, 0, 0, 1);
        }

        camera.zoom = MathUtils.clamp(camera.zoom, 1.5f, 1.8f);

        float effectiveViewportWidth = camera.viewportWidth * camera.zoom;
        float effectiveViewportHeight = camera.viewportHeight * camera.zoom;

        camera.position.x = MathUtils.clamp(camera.position.x, effectiveViewportWidth / 2f, width - effectiveViewportWidth / 2f);
        camera.position.y = MathUtils.clamp(camera.position.y, effectiveViewportHeight / 2f, height - effectiveViewportHeight / 2f);
    }

    @Override
    public boolean zoom(float initialDistance, float distance) {


        if (initialDistance >= distance) {
            camera.zoom += 0.02;
        } else {
            camera.zoom -= 0.02;
        }


        return false;
    }

    @Override
    public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2,
                         Vector2 pointer1, Vector2 pointer2) {

// TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean panStop(float x, float y, int pointer, int button) {
        // TODO Auto-generated method stub
        return false;
    }


    public void hide() {
        // TODO Auto-generated method stub

    }
\$\endgroup\$
2
  • \$\begingroup\$ A bit verbose since the OP has to read through the code example. Consider posting a summary at the top of your answer where you tell the OP that you can translate the camera to pan and set the camera's zoom to zoom. Then if that doesn't answer the question, the OP can delve into your code. \$\endgroup\$ Commented Mar 2, 2016 at 20:02
  • \$\begingroup\$ Sorry for the necro, I was scrolling through older questions/answers and this popped up and I forgot to accept ;-) \$\endgroup\$
    – Jax
    Commented Jun 26, 2018 at 20:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .