LibGDX开发中如何返回上一个Screen且不丢失用户修改的内容?
问题解答
关于LibGDX setScreen方法的基础说明
setScreen方法完全支持传入已经创建过的旧Screen实例,不存在只能传新实例的限制,你切换失败是代码存在语法和逻辑错误导致的。
你代码里的核心问题
- 语法错误:render方法提前闭合
你提供的代码里,render方法在按钮判断逻辑结束后多了一个闭合的},直接把stage.act()、stage.draw()两行代码排除在了render方法之外,导致界面永远不会绘制按钮、输入事件也不会触发,自然点击按钮没有任何反应。 - 逻辑错误:重复添加Actor
你把stage.addActor(saveAndContinue)写在了render方法里,每次界面渲染都会把同一个按钮重复添加到Stage中,会导致内存泄漏、输入事件响应异常。这行代码只需要在构造方法里执行一次即可,你构造里已经加过一次,render里的可以直接删掉。 - 点击检测逻辑不合理
isPressed()会在按钮按住的每帧都触发一次,很容易导致切屏逻辑重复执行,建议用ClickListener监听点击事件更稳妥。
保留Screen状态的标准实现方案
你想要切换后保留之前的操作修改,直接复用Screen实例就是官方推荐的标准方案,具体实现逻辑如下:
- 在你的Game子类中提前初始化所有需要复用的Screen实例,作为成员变量存储
- 切换Screen时直接把对应已经实例化的Screen对象传入
setScreen即可,Screen内的所有状态(包括用户操作的修改、控件状态等)都会完整保留 - 注意:只有当你确定某个Screen后续不会再使用时,再调用它的
dispose()方法释放资源,切换过程中不要随意销毁当前Screen,否则下次切回时会出现资源丢失的问题。如果需要切换时暂停当前Screen的逻辑,可以在hide()方法里做暂停背景音乐、取消输入监听等处理,show()方法里恢复即可。
修复后的核心代码示例
// 构造方法内给按钮添加点击监听,替换原有isPressed判断 saveAndContinue.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { game.setFirstTurn(false); game.setScreen(gameScreen); // 如果TroopPlacingScreen后续还要用就不要调用dispose,确定不用了再调 // TroopPlacingScreen.this.dispose(); } }); @Override public void render(float delta) { ScreenUtils.clear(0, 0, 0, 1); camera.update(); game.batch.setProjectionMatrix(camera.combined); game.batch.begin(); game.batch.end(); // 删掉这里重复的addActor代码 stage.act(delta); stage.draw(); }
内容的提问来源于stack exchange,提问作者SergeLover
相关产品推荐
相关产品推荐

