0
\$\begingroup\$

I'm starting with LibGDX and I loving it so far, but I have found some troubles and I'm getting a little frustrated. I've searched a lot for a solution and tried many things, but nothing seems to work. What I want to accomplish is basically a 2d map with a rts-like camera, in other words, a map/world bigger than the viewport where I can move the camera freely. The problem is I can't make the camera move, and I'm not even sure if my world is bigger than my viewport. How can I get these two things done? I'm sure I'm doing something wrong, but I can't figure what it is. Any help would be really appreciated.

These are my classes:

GameMain

public class GameMain extends Game {

private SpriteBatch batch;

@Override
public void create () {
    batch = new SpriteBatch();
    ScreenManager.getInstance().initialize(this);
    ScreenManager.getInstance().showScreen(ScreenEnum.WORLD);
}

@Override
public void render () {
    super.render();
}

public SpriteBatch getBatch() {
    return this.batch;
}
}

AbstractScreen

public abstract class AbstractScreen extends Stage implements Screen {
protected AbstractScreen() {
    super(new ScreenViewport(new OrthographicCamera()));
}

// Subclasses must load actors in this method
public abstract void buildStage();

@Override
public void render(float delta) {
    // Clear screen
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // Calling to Stage methods
    super.act(delta);
    super.draw();
}

@Override
public void show() {
    Gdx.input.setInputProcessor(this);
}

@Override
public void resize(int width, int height) {
    getViewport().update(width, height, true);
}

@Override public void hide() {}
@Override public void pause() {}
@Override public void resume() {}
}

ScreenEnum

public enum ScreenEnum {

WORLD {
    public AbstractScreen getScreen(GameMain game, Object... params) {
        return new WorldScreen(game);
    }
};

public abstract AbstractScreen getScreen(GameMain game, Object... params);
}

ScreenManager

public class ScreenManager {

// Singleton: unique instance
private static ScreenManager instance;

// Reference to game
private GameMain game;

// Singleton: private constructor
private ScreenManager() {
    super();
}

// Singleton: retrieve instance
public static ScreenManager getInstance() {
    if (instance == null) {
        instance = new ScreenManager();
    }
    return instance;
}

// Initialization with the game class
public void initialize(GameMain game) {
    this.game = game;
}

// Show in the game the screen which enum type is received
public void showScreen(ScreenEnum screenEnum, Object... params) {

    // Get current screen to dispose it
    Screen currentScreen = game.getScreen();

    // Show new screen
    AbstractScreen newScreen = screenEnum.getScreen(game, params);
    newScreen.buildStage();
    game.setScreen(newScreen);

    // Dispose previous screen
    if (currentScreen != null) {
        currentScreen.dispose();
    }
}
}

WorldScreen

public class WorldScreen extends AbstractScreen {

private GameMain game;
private Texture map;

public WorldScreen(GameMain game) {
    this.game = game;
    map = new Texture("sprites/maps/map.jpg");
}

@Override
public void buildStage() {

}

@Override
public void show() {

}

@Override
public void render(float delta) {
    super.render(delta);

    game.getBatch().begin();
    game.getBatch().draw(map, 0, 0);
    game.getBatch().end();
    this.getCamera().translate(+500, +500, 0);
    this.getCamera().update();
}

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

}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {

}
}

I debugged the camera and it's changing its value position, but it's not being reflected in the screen.

Also, is there a way to prevent the map texture from being scaled when resizing?

\$\endgroup\$
1
\$\begingroup\$

This is because you are not updating the projectionMatrix of the SpriteBatch. You have to update the projection matrix otherwise the batch will not know what do display on screen.

To fix this simply add game.getBatch().setProjectionMatrix(this.getCamera().combined); before your batch.begin() in your WorldScreen and anywhere else you use the batch.

Your update should now look like this:

@Override
public void render(float delta) {
    super.render(delta);

    // Important line right here
    game.getBatch().setProjectionMatrix(this.getCamera().combined);
    game.getBatch().begin();
    game.getBatch().draw(map, 0, 0);
    game.getBatch().end();
    this.getCamera().translate(+500, +500, 0);
    this.getCamera().update();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.