How to refresh a transparent screen in libGdx

  Kiến thức lập trình

I am working on a small libGdx project at the moment and I am facing now some trouble concerning a transparent screen. This transparent screen is called ‘GameMenuScreen’ because it can be called throughout the game. If it is called the ‘GameMenuScreen’ is rendered above the GameScreen which is still visible in the background. Now when I press e.g. the ‘Save’ button, all of the buttons duplicate. I think it occurs because the screen isn’t refreshed every frame. But for now I have no idea how to refresh the screen and preserve its transparency.
Here is the Code of the ‘GameMenuScreen’:

public class GameMenuScreen extends ScreenAdapter {

    private TextureAtlas uiskinAtlas;
    private Skin skin;
    private OrthographicCamera camera;
    private Viewport viewport;
    private Stage stage;
    private Table table;
    private Vector3 position;
    private SpriteBatch batch;

    private TextButton continueGame;
    private TextButton loadGame;
    private TextButton settings;
    private TextButton mainMenu;
    private TextButton quit;
    private TextButton save;

    public GameMenuScreen() {
        
        uiskinAtlas = GameWindow.manager.get(Paths.uiskinAtlas, TextureAtlas.class);
        skin = new Skin(Gdx.files.internal(Paths.uiskinJson), uiskinAtlas);
        camera = new OrthographicCamera();
        position = new Vector3(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 0);
        camera.position.set(position);
        viewport = new ScreenViewport(camera);
        stage = new Stage(viewport);
        batch = new SpriteBatch();

        table = new Table();
        
        continueGame = new TextButton("Continue Game", skin);
        loadGame = new TextButton("Load Game", skin);
        settings = new TextButton("Settings", skin);
        mainMenu = new TextButton("Main Menu", skin);
        quit = new TextButton("Quit", skin);
        save = new TextButton("Save", skin);
        
        
        continueGame.setColor(Color.ROYAL);
        loadGame.setColor(Color.ROYAL);
        settings.setColor(Color.ROYAL);
        mainMenu.setColor(Color.ROYAL);
        quit.setColor(Color.ROYAL);
        save.setColor(Color.ROYAL);
        
        createUI();
    }

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

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 0f);
        
        batch.enableBlending();
        batch.begin();
        continueGame.draw(batch, 0);
        loadGame.draw(batch, 0);
        settings.draw(batch, 0);
        mainMenu.draw(batch, 0);
        quit.draw(batch, 0);
        save.draw(batch, 0);
        batch.end();
        
        stage.act();
        stage.draw();
    }

    private void createUI() {
        
        table.setFillParent(true);
        table.center();

        setButtonInput();

        table.add(continueGame).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(loadGame).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(save).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(settings).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(mainMenu).width(250);
        table.row().space(5, 5, 0, 0);
        table.add(quit).width(250);
        table.row().space(5, 5, 0, 0);

        stage.addActor(table);
        
    }

    private void setButtonInput() {

        continueGame.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                GameWindow.INSTANCE.setScreen(Screens.getGameScreen());
            }
        });

        loadGame.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Savegame.load();
                Screens.getGameScreen().setWorldCreated(false);
                GameWindow.INSTANCE.setScreen(Screens.getGameScreen());
            }
        });

        save.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Savegame.save();
            }
        });

        mainMenu.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                GameWindow.INSTANCE.setScreen(Screens.getMainMenuScreen());
            }
        });

        quit.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Gdx.app.exit();
            }
        });
    }
    
    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
        position = new Vector3(viewport.getScreenWidth() / 2, viewport.getScreenHeight() / 2, 0);
        camera.position.set(position);
    }

The normal way to refresh the screen every frame is to call this two code pieces:

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

But as mentioned before: the screen loses its transparency when it is called.

For better understanding one picture showing the doupling:

I hope you can help me.

New contributor

Morgoth is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1

LEAVE A COMMENT