LibGDX游戏暂停状态:动画闪烁/错误。

3
我正在尝试为我的游戏实现暂停选项。按下后退按钮后,我的游戏应该进入updatePause()方法。但它反而重复渲染最新的2-3帧,看起来像是“闪烁”。
为了防止这种情况,我已经添加了(在注释中)不连续渲染,这样可以防止闪烁。但是,如果按下后退按钮超过一次,会渲染另一帧(其中之一是闪烁帧)。这是我的代码结构简述:
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;
        }
    }
}

有什么技巧可以防止闪烁?

不要停止绘制,继续绘制最新的帧(不要更新游戏模型,而是继续渲染)。这应该可以解决问题。 - Twometer
@Twometer 当我注释掉持续渲染时,闪烁就会发生。或者你具体指的是什么? - Manh Khôi Duong
3个回答

4

render()方法是用来将内容绘制到屏幕上的。如果未能成功绘制,那么后台缓冲区中的内容将是未定义的(可能会包含之前的帧),从而导致闪烁。

禁用连续渲染听起来是一个不错的方法。或者,即使游戏暂停也要继续绘制。


禁用持续渲染可以节省电量,所以我会坚持使用它。如何清除“后备缓冲区”中的内容?正如您所看到的,绘制是在updateRunning()函数中发生的。我找不到有关后备缓冲区的任何信息。是否有任何文档可用? - Manh Khôi Duong
只需查找“双缓冲”,这是一种标准技术,不特定于libGDX。我希望关闭连续渲染也会禁用缓冲区交换,但我还没有检查过。这篇文章可能会有所帮助:http://bitiotic.com/blog/2012/10/01/enabling-non-continuous-rendering-in-libgdx/ - Thomas
我已经阅读了那篇文章。但是感谢您建议查找双缓冲区。 - Manh Khôi Duong

1
正如Thomas在他的答案中指出的那样。它应该在每一帧绘制。
我还没有看到你在屏幕上画任何东西,所以后备缓冲区可能只包含垃圾信息。解决这个问题的一种方法是始终在render()的顶部清除屏幕。这意味着当你立即切换到另一个游戏状态时,它会确保屏幕清晰,并且不会出现您经历过的闪烁结果。
public void render(float deltaTime) {
    // clear screen
    Gdx.gl.glClearColor(0f, 0f, 0f, 1.0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    ...
}

我的真实代码实际上绘制了很多东西。有很多事情正在进行,但我剪掉了我认为与这个问题无关的代码片段。这就是为什么我说这只是一个简短的“代码结构”。 - Manh Khôi Duong
清空屏幕并不能解决问题,因为进入暂停状态会使屏幕变黑,但我仍然想看到正在发生的事情。 - Manh Khôi Duong

0

正如Thomas所说:继续绘制是解决问题的一种方法。因此,我绘制了最新的帧并在此之后禁用了连续渲染。结果完全没有错误,并且让CPU得到了休息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接