Burnt_Toast6
Burnt_Toast6

Reputation: 3

Libgdx: Translating a Scene2d Camera

I'm working on a tile based game with Libgdx that moves the map using WASD. I'm using the scene2d features to draw the screen, and the TiledMap that I'm rendering shows up just fine. But when I try and call the stage.getCamera().translate(float x, float y, float z); method to move the viewport with Gdx.Input.IsKeyPressed() method, the viewport does not translate. The method is getting called, because "KEY PRESSS" is being output onto the console, but the camera is not translating. Is there another method to moving the viewport? Does the Stage class have some other method to move the camera?

Here's my source for the Screen:

package com.BurntToast.SolidDiamond;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.viewport.FitViewport;


public class PlayScreen implements Screen {



private MainFrame mainFrame;

    private OrthographicCamera camera;
    private Vector3 touchCoord;
    private TiledMap currentMap;
    private OrthogonalTiledMapRenderer otmr;

    private ConveyorActor convActor;

    private Stage mapStage;


    public PlayScreen(MainFrame passedGame){
        mainFrame = passedGame;

        convActor = new ConveyorActor(mainFrame.conveyorFrames, 1, 0, 0);
        mapStage = new Stage();
        mapStage.addActor(convActor);
        currentMap = new TmxMapLoader().load("maps/MenuMap2.tmx");
        otmr = new OrthogonalTiledMapRenderer(currentMap);
        otmr.setView((OrthographicCamera)mapStage.getCamera());

    }
    @Override
    public void render(float delta) {
        // TODO Auto-generated method stub
        //ERIC (erase, redraw, input, calculate)
        //ERASE
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        //camera.update();

        //REDRAW
        otmr.render();
        mapStage.draw();


        //INPUT/CALCULATE
        mapStage.act();
        if(Gdx.input.isTouched()){

        }//end if touched

        //MAP TRANSLATION INPUT HERE:
        if(Gdx.input.isKeyPressed(Keys.W)){
            //heres the line of code but it won't translate.
            mapStage.getCamera().translate(0, 10, 0);
            mapStage.getCamera().update();
            System.out.println("KEY PRESSS");
        }
        if(Gdx.input.isKeyPressed(Keys.A)){
            mapStage.getCamera().translate(-10, 0, 0);
            mapStage.getCamera().update();
        }
        if(Gdx.input.isKeyPressed(Keys.S)){
            mapStage.getCamera().translate(0, -10, 0);
            mapStage.getCamera().update();
        }
        if(Gdx.input.isKeyPressed(Keys.D)){
            mapStage.getCamera().translate(10, 0, 0);
            mapStage.getCamera().update();
        }
    }



    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void show() {
        // TODO Auto-generated method stub
        mapStage = new Stage(new FitViewport(mainFrame.SCREEN_WIDTH, mainFrame.SCREEN_HEIGHT));
    }

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

    }

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

    }

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

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub
        currentMap.dispose();
    }

Upvotes: 0

Views: 1209

Answers (1)

Tenfour04
Tenfour04

Reputation: 93609

In PlayScreen's constructor, you create a mapStage which will have its own viewport and camera. Then you give that camera to the tiled map renderer.

But then in show(), you create a new mapStage which will replace the reference that was created in the constructor. So when you are changing the camera in render(), it is the camera from the new stage, not the old camera that the tiled map renderer is still using.

You'll want to avoid using new Stage(...) in the show method anyway, because then you'll be creating a new Stage every time the screen changes, which will waste time creating a new sprite batch (which takes up a lot of memory and compiles a shader each time). And the old stage that you replace each time will leak because it's not having dispose() called on it before its reference is lost.

I'm not sure of your constraints, but one solution would be to revise your show method to this:

public void show() {
    mapStage.setViewport(new FitViewport(mainFrame.SCREEN_WIDTH, mainFrame.SCREEN_HEIGHT));
    otmr.setView((OrthographicCamera)mapStage.getCamera());
}

A couple of other things... You should dispose of your stage in dispose() to avoid potential leaks (the sprite batch in the stage will leak a shader when the screen changes if you don't). And your camera movements should always involve multiplying by delta so the movement speed is framerate independent.

Upvotes: 1

Related Questions