2
\$\begingroup\$

I want to add buttons to my libgdx based game and have them be independent of the window's size, but when I resize the window, the buttons stretch and deform instead of being resized and/or moved.

Most answers online say that this problem can be solved by resizing the stage's viewport, but I am already doing that and it confuses me, because I have no clue what the problem could be. To me it just looks like it is drawing to a texture that gets initialized to whatever size my window initially has, and is then stretched but never resized. Am I using it wrong? Or do I need to do something else?

What I start with:

initial buttons layout

What I end up with:

buttons after resizing the window

What I actually want (made with paint):

how I want it to look like

My code:

MainMenuScreen.java

public class MainMenuScreen implements Screen
{
    private Stage stage;
    private Table table;

    private MyGame game;

    public MainMenuScreen(MyGame game)
    {
        this.game = game;

        table = new Table();
        table.setFillParent(true);

        stage = new Stage();
        stage.addActor(table);

        Gdx.input.setInputProcessor(stage);

        // FIXME testing
        Skin skin = new Skin(Gdx.files.internal("skins/default/skin/uiskin.json"));
        
        TextButton button1 = new TextButton("Sandwich", skin);
        table.add(button1);

        TextButton button2 = new TextButton("Kebab", skin);
        table.add(button2);
    }

    @Override
    public void show()
    {

    }

    @Override
    public void render(float delta)
    {
        Gdx.gl.glClearColor(0, 0.2f, 0.3f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        stage.act(delta);
        stage.draw();
    }

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

    @Override
    public void dispose()
    {
        stage.dispose();
    }
}

MyGame.java

public class MyGame extends Game
{
    public SpriteBatch batch;
    public Input input;

    private MainMenuScreen mainMenuScreen;

    @Override
    public void create()
    {
        batch = new SpriteBatch();

        input = new Input();
        Gdx.input.setInputProcessor(input);

        mainMenuScreen = new MainMenuScreen(this);
        setScreen(mainMenuScreen);
    }

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

    @Override
    public void dispose()
    {
        mainMenuScreen.dispose();
        batch.dispose();
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Looks like you have the opposite issue of what is described here, maybe checking the difference between what they did and what you have could help? \$\endgroup\$
    – Vaillancourt
    Aug 24, 2021 at 16:01
  • 1
    \$\begingroup\$ Good catch, they are using a viewport which I am not, and adding one makes it work the desired way. \$\endgroup\$
    – happun
    Aug 24, 2021 at 19:27

1 Answer 1

1
\$\begingroup\$

It seems that a viewport is missing, as adding one yields the desired behaviour. The following code works for this purpose:

MainMenuScreen.java

public class MainMenuScreen implements Screen
{
    private Stage stage;
    private Table table;

    private OrthographicCamera camera;
    private FitViewport viewport;

    private MyGame game;

    public MainMenuScreen(MyGame game)
    {
        this.game = game;

        this.camera = new OrthographicCamera();
        this.viewport = new FitViewport(0, 0, camera);

        table = new Table();
        table.setFillParent(true);

        stage = new Stage();
        stage.setViewport(viewport);
        stage.addActor(table);

        Gdx.input.setInputProcessor(stage);

        // FIXME testing
        Skin skin = new Skin(Gdx.files.internal("skins/default/skin/uiskin.json"));
        
        TextButton button1 = new TextButton("Sandwich", skin);
        table.add(button1);

        TextButton button2 = new TextButton("Kebab", skin);
        table.add(button2);
    }

    @Override
    public void show()
    {

    }

    @Override
    public void render(float delta)
    {
        Gdx.gl.glClearColor(0, 0.2f, 0.3f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        stage.act(delta);
        stage.draw();
    }

    @Override
    public void resize(int width, int height)
    {
        camera.setToOrtho(false, width, height);
        viewport.setWorldSize(width, height);
        stage.getViewport().update(width, height, true);   
    }

    @Override
    public void dispose()
    {
        stage.dispose();
    }
}
\$\endgroup\$

You must log in to answer this question.

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