2015-07-02 172 views
0

我有一个问题,我认为它与屏幕渲染及其生命周期有关。 基本上我有两个屏幕(菜单和游戏)。在GameScreen渲染方法中,我调用World.update,之后渲染。在(GameScreen的)隐藏方法中,我从Redner类处理SpriteBatch。LibGdx屏幕:渲染和生命周期

所以,当我将游戏切换到菜单(在World.update内)时,Java会崩溃。据我所知,处置正在造成崩溃。 所以我的问题是,当我在渲染周期的中间设置一个新的屏幕时,渲染周期是否仍然完成其旧屏幕?这意味着,我在渲染完成之前调用了batch.dispose,这就是为什么我会遇到问题?

谢谢所有帮助

public class GameScreen extends AbstractGameScreen { 
    private static final String TAG = GameScreen.class.getName(); 

    private WorldController worldController; 
    private WorldRenderer worldRenderer; 

    private boolean paused; 

    public GameScreen(Game game) { 
     super(game); 
    } 

    @Override 
    public void render(float deltaTime) { 
     // Do not update game world when paused 
     if (!paused) { 
      // Update game world by the time that has passed since last render time 
      worldController.update(deltaTime); 
     } 
     // Sets the clear screen color to: Cornflower Blue 
     Gdx.gl.glClearColor(0x64/255.0f, 0x95/255.0f, 0xed/255.0f, 0xff/255.0f); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
     // Render game world to screen 
     worldRenderer.render(); 
    } 

    @Override 
    public void resize(int width, int height) { 
     worldRenderer.resize(width, height); 
    } 

    @Override 
    public void show() { // Similar as create method 
     worldController = new WorldController(game); 
     worldRenderer = new WorldRenderer(worldController); 
     Gdx.input.setCatchBackKey(true); 
    } 

    @Override 
    public void hide() { // Similar to dispose method 
     worldRenderer.dispose(); 
     Gdx.input.setCatchBackKey(false); 
    } 

    @Override 
    public void pause() { 
     paused = true; 
    } 

    @Override 
    public void resume() { 
     super.resume(); 
     // Only called on Android 
     paused = false; 
    } 
} 

回答

1

这基本上是正确的。从render方法中调用setScreen的屏幕将自己调用hide,然后将继续执行其render方法中的其余代码。因此,在尝试绘制它之前,你正在杀死你的sprite批处理。

因此,请勿在hide方法中调用dispose。实际上,屏幕可能自己调用​​dispose的做法可能是不好的做法。您可以为拥有它的Game类保留该类。例如,你可以做你的游戏类是这样的:

@Override 
public void render() { 
    super.render(); 
    if (getScreen() != gameScreen && gameScreen != null) { 
     gameScreen.dispose(); 
     gameScreen = null; 
    } 
} 

顺便说一句,你应该把SpriteBatch在你的游戏子类,并让所有的不同的屏幕共享。无缘无故分配和释放是一个相当大的对象。

+0

完美,谢谢。还有一个问题。看着我的两个屏幕(主菜单和游戏)。在他们之间切换,生活或处置它们时,最佳做法是什么。如果我不处理它们,我应该在menuScreen中处理GameScreen的SpriteBatch吗? – JakaK

+0

SpriteBatch应该只在游戏完全关闭时放置(在您的Game类的'dispose'方法中),因为您在每个屏幕上都需要它。释放它并分配一个新的是浪费时间。对于整个屏幕来说,没有最佳做法,因为它取决于游戏。我正在做一个非常简单的游戏,我可以随时轻松地将整个游戏保存在内存中,所以我从不处理屏幕。但是如果你的记忆力增加,你可能需要。菜单屏幕可能不会使用太多,所以除了从一个阶段切换到另一个阶段时,可能总是保持屏幕。 – Tenfour04