Search code examples
javalibgdx

Libgdx Switching Screens and Viewports


I am having an issue when switching screens in libgdx. I am building a asteroids game clone. So first my MainMenuScreen class (which uses a Fitviewport) is rendered and then I call setScreen() to GameScreen (GameScreen doesn't use a Fitviewport) and that works except that the second screen renders as if its using a Fitviewport. If I resize the second screen then the whole window is used for rendering. Why is this happening? Here are some pictures:

MainMenuScreen class:

Image 1

GameScreen class after switching screens, the screen has black bars on the side (I colored the boundary in red for you) which I don't want:

Image 2

I want the GameScreen to use all the window area for rendering, and not have black bars like the MainMenu. I am not using any Fitviewport in GameScreen also.

Here are relevant parts of my MainMenuScreen class:

public class MainMenuScreen implements Screen
{
    private static final String TAG = "MainMenu";
    private static final int VIRTUAL_WIDTH = 400;
    private static final int VIRTUAL_HEIGHT = 400;
    MyGdxGame game;

       ...

    public MainMenuScreen(MyGdxGame game)
    {

        this.game = game;
        viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
        stage = new Stage(viewport);

        // Play button listener
        btnPlay.addListener( new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Gdx.app.log(TAG, "PLAY");
              MainMenuScreen.this.game.setScreen(MainMenuScreen.this.game.gameScreen);
            };
        });

             ....
    }

Here is my GameScreen class:

MyGdxGame game;
OrthographicCamera guiCam;
World world;
WorldRenderer renderer;


public GameScreen(MyGdxGame game, SpriteBatch batch)
{
    this.game = game;
    guiCam = new OrthographicCamera(400, 400);
    guiCam.position.set(400 / 2, 400 / 2, 0);
    world = new World();
    renderer = new WorldRenderer(game, batch, world);
}

public void draw()
{
    GL20 gl = Gdx.gl;
    gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    renderer.render();
}

@Override
public void show()
{
    world.createLevel();
}

@Override
public void render(float delta)
{
    draw();
}

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

}

@Override
public void pause()
{

}

@Override
public void resume()
{

}

@Override
public void hide()
{

}

@Override
public void dispose()
{

}

Solution

  • The problem is this line of code:

    public void resize(int width, int height)
        {
            viewport.update(width, height, true);
    
        }
    

    Whenever you update the viewport, you are also updating the underlying opengl viewport and this causes the black bars to persist to the second screen (https://github.com/libgdx/libgdx/wiki/Viewports). Thus if you want to reset it back to normal you must use the following line of code in your second screen show() method (https://github.com/libgdx/libgdx/wiki/Scene2d):

    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());