[LibGDX] TiledMap, Textures and Zoom

Hi guys!

I’m creating a builder style game and using TiledMap and LIBGDX. So, I’m just testing the camera and translation and having some issues with zoom. All works perfect without changing the zoom. But when I change it, the Texture/Sprite becomes misaligned with the Tiled. The actors continue just fine, but the textures/sprites not. I don’t know how to correct the scale in the update.

So, how could I correct the zoom for the TextureRegion (and Sprites)? My code is above:



public class TiledTest extends ApplicationAdapter {
    
    private static final String TAG = TiledTest.class.getName();
    
    Texture img;
    TiledMap tiledMap;
    OrthographicCamera camera;    
    TiledMapRenderer tiledMapRenderer;
    SpriteBatch batch;
    Sprite sprite;
    Actor actor;
    Stage stage;
    boolean init = false;
    
    @Override
    public void create () {
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        batch = new SpriteBatch();
        camera = new OrthographicCamera();

        
        camera.setToOrtho(false,w,h);
        camera.update();
        
        
        InternalFileHandleResolver handle = new InternalFileHandleResolver();
        handle.resolve("mapa_teste.tmx");
        TmxMapLoader loader = new TmxMapLoader(handle);        
        tiledMap = loader.load("img/mapas/mapa_teste.tmx");
        
        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);        
        
        sprite = new Sprite(new Texture(Gdx.files.internal("img/tanque_192x192.png")));
        sprite.setBounds(128, 128, sprite.getTexture().getWidth(), sprite.getTexture().getHeight());
        stage = new Stage();
        actor = new Actor();
        actor.setBounds(128,128, 192, 192);
        actor.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                super.clicked(event, x, y);
                Gdx.app.log(TAG, "Tanque clicado!");
            }

            @Override
            public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
                super.exit(event, x, y, pointer, toActor);
                if(pointer == -1)
                    Gdx.app.log(TAG, "Mouse saindo do actor!");                
            }

            @Override
            public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                super.enter(event, x, y, pointer, fromActor);
                if(pointer == -1)
                    Gdx.app.log(TAG, "Mouse entrando no actor!");                
            }
                     
        });
        stage.addActor(actor);                
        Gdx.input.setInputProcessor(stage);
        stage.getViewport().setCamera(camera);
        stage.setDebugAll(true);
        
        
    }

    @Override
    public void render () {

        input();
        
        Gdx.gl.glClearColor(0, 0.5f, 0.5f, 1);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        camera.update();
        tiledMapRenderer.setView(camera);
        tiledMapRenderer.render();
        
        batch.begin();
        sprite.draw(batch);
        batch.end();
        
        stage.act();
        stage.draw();        

    }

    
    public void input(){
        
        float cameraSpeed = 7f;
        
        if(Gdx.input.isKeyPressed(Input.Keys.S)){
            camera.translate(0f, +cameraSpeed);
            sprite.translate(0f, -cameraSpeed);
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.W)){
            camera.translate(0f, -cameraSpeed);            
            sprite.translate(0f, +cameraSpeed);            
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.A)){
            camera.translate(-cameraSpeed, 0f);            
            sprite.translate(+cameraSpeed, 0f);            
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.D)){
            camera.translate(+cameraSpeed, 0f);            
            sprite.translate(-cameraSpeed, 0f);            
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.F2)){
            camera.zoom += 0.01f;
            //sprite.scale(camera.zoom);
        }if(Gdx.input.isKeyPressed(Input.Keys.F3)){
            camera.zoom -= 0.01f;            
            //sprite.scale(camera.zoom);
        }
        if(Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)){
            stage.dispose();
            batch.dispose();
            tiledMap.dispose();
            sprite.getTexture().dispose();
            Gdx.app.exit();
        }
        
    }
    
}

So, I finally figure out a solution. First, not using a Texture. Now I’m using a TextureMapObject. That way, is a must to create a MapObjectLayer also in Tiled.

Include the batch.setProjectionMatrix(camera.combined) before batch.begin().

And also draw manually using batch.draw(). It follows the final code for anyone struggling:

public class TiledTest extends ApplicationAdapter {
    
    private static final String TAG = TiledTest.class.getName();
    
    TextureMapObject tmo;
    TiledMap tiledMap;    
    OrthographicCamera camera;    
    TiledMapRenderer tiledMapRenderer;
    SpriteBatch batch;    
    Texture texture;
    Actor actor;
    Stage stage;

    
    
    @Override
    public void create () {
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();
        
        batch = new SpriteBatch();
        camera = new OrthographicCamera();
        
        camera.setToOrtho(false,w,h);
        camera.update();        
        
        
        InternalFileHandleResolver handle = new InternalFileHandleResolver();
        handle.resolve("mapa_teste.tmx");
        TmxMapLoader loader = new TmxMapLoader(handle);        
        tiledMap = loader.load("img/mapas/mapa_teste.tmx");
        
        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
        
        //TextureMapObject
        texture = new Texture(Gdx.files.internal("img/tanque_192x192.png"));
        tmo = new TextureMapObject(new TextureRegion(texture,192,192));
        tmo.setX(128);
        tmo.setY(128);
        tiledMap.getLayers().get("Objects").getObjects().add(tmo);
        stage = new Stage();
        actor = new Actor();
        actor.setBounds(128,128, tmo.getTextureRegion().getRegionWidth(), tmo.getTextureRegion().getRegionHeight());
        actor.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                super.clicked(event, x, y);
                Gdx.app.log(TAG, "Tanque clicado!");
            }

            @Override
            public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
                super.exit(event, x, y, pointer, toActor);
                if(pointer == -1)
                    Gdx.app.log(TAG, "Mouse saindo do actor!");                
            }

            @Override
            public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                super.enter(event, x, y, pointer, fromActor);
                if(pointer == -1)
                    Gdx.app.log(TAG, "Mouse entrando no actor!");                
            }
                     
        });
        stage.addActor(actor);                
        Gdx.input.setInputProcessor(stage);
        stage.getViewport().setCamera(camera);
        stage.setDebugAll(true);        

        
    }

    @Override
    public void render () {

        input();
        
        Gdx.gl.glClearColor(0, 0.5f, 0.5f, 1);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        camera.update();
        tiledMapRenderer.setView(camera);
        tiledMapRenderer.render();
        
        batch.setProjectionMatrix(camera.combined);
        batch.begin();        
        
        batch.draw(tmo.getTextureRegion(), tmo.getX(), tmo.getY(),
                tmo.getOriginX(), tmo.getOriginY(), tmo.getTextureRegion().getRegionWidth(), tmo.getTextureRegion().getRegionHeight(),
                tmo.getScaleX(), tmo.getScaleY(), tmo.getRotation());       
        
        batch.end();
        
        
        stage.act();
        stage.draw();        


    }

    
    public void input(){
        
        float cameraSpeed = 7f;
        
        if(Gdx.input.isKeyPressed(Input.Keys.S)){
            camera.translate(0f, +cameraSpeed);            
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.W)){
            camera.translate(0f, -cameraSpeed);                        
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.A)){
            camera.translate(-cameraSpeed, 0f);                        
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.D)){
            camera.translate(+cameraSpeed, 0f);                        
        } 
        if(Gdx.input.isKeyPressed(Input.Keys.F2)){
            camera.zoom += 0.01f;
        }if(Gdx.input.isKeyPressed(Input.Keys.F3)){
            camera.zoom -= 0.01f;
        }
        if(Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)){
            stage.dispose();
            batch.dispose();
            tiledMap.dispose();            
            Gdx.app.exit();
        }
        
    }
    
}