3

Im trying to implement a pause option for my following game. By pressing the back button my game should go to the updatePause() method. But instead it renders the latest 2-3 frames repeatedly. Making it look like it's "flickering".

By trying to prevent this I've added (in the comments) non-continously rendering which prevented the flickering. But then Im facing the problem that pressing the back-button more than once will render another frame. (one of those flickering frames). This is my code structure in short:

public class GameScreen implements Screen {
    private static final int GAME_RUNNING = 0;
    private static final int GAME_PAUSED = 1;
    private static final int GAME_OVER = 2;
    private static final int GAME_LEVEL_END = 3;
    private int gameState;

    private GdxGame game;

    //create()
    public GameScreen(final GdxGame game) {
        //create all the stuff
    }

    @Override
    public void render(float deltaTime) {
        switch (gameState) {
            case GAME_RUNNING:
                updateRunning(deltaTime);
                break;
            case GAME_PAUSED:
                updatePause(deltaTime);
                break;
            case GAME_OVER:
                updateGameOver();
                break;
        }
    }

    public void updateRunning(float deltaTime) {
        //draw section
        if (gameState == GAME_RUNNING) {
            game.batch.begin();
            //Draw some stuff
            game.batch.end();

            //move section
            handleInput();
        }
    }

    public void updatePause(float deltaTime) {
        //Gdx.graphics.setContinuousRendering(false);
        //resume
        if (Gdx.input.isTouched()) {
            gameState = GAME_RUNNING;
            //Gdx.graphics.setContinuousRendering(true);
            return;
        }
    }

    private void handleInput() {
        //catch back button
        Gdx.input.setCatchBackKey(true);
        if (Gdx.input.isKeyJustPressed(Input.Keys.BACK)) {
            gameState = GAME_PAUSED;
            return;
        }
    }
}

Any tips to prevent the flickering?

Juan Carlos Mendoza
  • 5,736
  • 7
  • 25
  • 50
  • Do not stop drawing and continue drawing the latest frame (do not update your game model, but continue to render). This should fix the issue. – Twometer Sep 06 '17 at 18:02
  • @Twometer The flickering happens when I comment out the continous rendering. Or what do you mean exactly? – Manh Khôi Duong Sep 07 '17 at 00:23

3 Answers3

4

The render() method is supposed to draw something to the screen. If it doesn't, then the contents of the back buffer will be undefined (so may contain a previous frame) and you get this flicker.

Disabling continuous rendering sounds like a good approach. Alternatively, continue drawing even if the game is paused.

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Disabling continous rendering will save battery, so I will stay with that. How do I get rid of the contents in the "back buffer"? As you can see, the drawing happens in `updateRunning()`. I couldn't find any infos about the back buffer. Any docs available? – Manh Khôi Duong Sep 07 '17 at 00:32
  • Just look up "double buffering", it's a standard technique not specific to libGDX. I would expect that turning off continuous rendering would also disable buffer swapping, but I haven't checked. This article might be helpful: http://bitiotic.com/blog/2012/10/01/enabling-non-continuous-rendering-in-libgdx/ – Thomas Sep 07 '17 at 07:05
  • Ive already read that article. But thank you for advicing to look up to double buffering. – Manh Khôi Duong Sep 07 '17 at 14:59
1

As Thomas points out in his answer. It should be drawing every frame.

I haven't see you draw anything on screen yet, so backbuffer might just contain junk information. One way to solve this is to always clear the screen at the top of render(). This means when you switch immediately to another game state, it will make sure that screen is clear and no flickering result as you experienced.

public void render(float deltaTime) {
    // clear screen
    Gdx.gl.glClearColor(0f, 0f, 0f, 1.0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    ...
}
haxpor
  • 2,431
  • 3
  • 27
  • 46
  • My real code actually draws a lot of stuff. There is a lot of stuff going on but I cut off code snippets which I dont find relevant for this problem. That's why I said that this is just a "code structure" in short. – Manh Khôi Duong Sep 07 '17 at 15:01
  • Clearing out the screen doesn't help because getting into the pause state will turn the screen black but I still want to see whats going on. – Manh Khôi Duong Sep 07 '17 at 15:02
0

As Thomas said: continue drawing is a way to fix it. So I drew the latest frame and disabled continous rendering after that. The result is having no bug at all and giving the CPU a rest.