Search code examples
javalibgdx

LibGDX Screen Resize with ClickListener


I am trying to create a simple platformer game using Java and LibGDX.

However, whenever I resize the menu screen, I have issues with my ClickListeners. The ClickListeners are not 'listening' at the right place in the screen.

I have a feeling that camera.unproject(); might work but I don't know where to implement it.

I have looked at many questions on Stack Overflow but have not found an answer that works.

Here is my code:

package uk.threepp.scrollfusion.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import uk.threepp.scrollfusion.Const;
import uk.threepp.scrollfusion.ScrollFusionMain;
import uk.threepp.scrollfusion.transition.Animation;
import uk.threepp.scrollfusion.transition.TransitionScreenScene2D;

public class ScreenMenuMain extends TransitionScreenScene2D {

    //region Variable Declarations
    private ScrollFusionMain game;

    private Stage stage;
    private OrthographicCamera cam;
    private Table menuTable;
    private Music music;

    private Skin menuSkin;

    private TextButton
            buttonPlay,
            buttonExit;
    //endregion

    public ScreenMenuMain(final ScrollFusionMain g) {

        game = g;

        cam = new OrthographicCamera();
        cam.setToOrtho(false, Const.SCREEN_WIDTH, Const.SCREEN_HEIGHT);

        game.batch.setProjectionMatrix(cam.combined);

        stage = new Stage(
                    new StretchViewport(
                        1280, 720, cam),
                game.batch);

        TextureAtlas atlas = new TextureAtlas("ui/MenuButton.pack");
        menuSkin = new Skin(Gdx.files.internal("ui/MenuButton.json"), atlas);

        menuTable = new Table(menuSkin);
        menuTable.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

        buttonPlay = new TextButton("Play", menuSkin);
        buttonExit = new TextButton("Exit", menuSkin);
        Label title = new Label("Scroll Fusion", menuSkin);

        //region Button Listeners
        buttonPlay.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                //TransitionHandler.transitionFadeOutToScreen(stage, Const.TRANSITION_SPEED, game, new ScreenGame(game));
                game.setScreen(new ScreenGame(game));
                dispose();
            }

            @Override
            public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                buttonPlay.setColor(0, 1, 0, 1);
            }

            @Override
            public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                buttonPlay.setColor(1, 1, 1, 1);
            }
        });

        buttonExit.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Gdx.app.exit();
            }

            @Override
            public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                buttonExit.setColor(1, 0, 0, 1);
            }

            @Override
            public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor) {
                buttonExit.setColor(1, 1, 1, 1);
            }
        });
        //endregion

        menuTable.add(title).padBottom(40).row();
        menuTable.add(buttonPlay).row();
        menuTable.add(buttonExit).row();

        menuTable.setFillParent(true);
        stage.addActor(menuTable);

        music = Gdx.audio.newMusic(Gdx.files.internal("music/Music01.wav"));

        Gdx.input.setInputProcessor(stage);
    }

    //region Methods from Screen Interface
    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

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

        transitionUpdate(delta);
        Gdx.app.log("FPS", String.valueOf(1/delta));

        menuTable.getCell(buttonPlay);
    }




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

        stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
        menuTable.setClip(true);
        menuTable.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    }




    @Override
    public void show() {
        music.setLooping(true);
        music.play();
        addTransition(Animation.fadeIn, Const.TRANSITION_SPEED);
    }




    @Override
    public void hide() {
    }




    @Override
    public void pause() {
    }




    @Override
    public void resume() {
    }




    @Override
    public void dispose() {
        stage.dispose();
        music.dispose();
        menuSkin.dispose();
    }
    //endregion
}

Solution

  • I have recently solved the solution.

    IntelliJ IDEA just needed a refresh. If this happens to you, modify your build.gradle file (e.g. add a random line break then delete it).

    The software will then come up with a prompt to resync your gradle project files; click 'Yes'.