Java游戏在更快的CPU上出现卡顿问题

4

我正在阅读一本有关Android游戏编程的书(《初学者指南:Android游戏开发》),并开始制作自己的游戏。

这是一个使用该书框架的Java游戏。(该书在转向Android之前先介绍了Java制作游戏的方法。)

无论如何,我制作了我的游戏,并且在我的笔记本电脑上流畅运行,它配备了一颗适中的i3处理器2.4GHz,我基本上在这台电脑上进行了所有的编码和测试。

我买了一台新的桌面电脑,上面搭载了一颗i5 3.3 GHz处理器,所以我决定在那里试玩我的游戏。

然而,在我看来速度更快的桌面电脑上,游戏似乎运行得非常卡顿。有一种顿挫感出现了,但我不知道是什么原因,因为我没有改变任何代码。

我的增量在两台机器上都很稳定,我应该得到平滑的60帧/秒,但桌面上却没有这样流畅。

我注意到减少最大休眠时间(基本上提高帧率)好像有点帮助,但我的所有功能都基于最大60fps。

我不太擅长这个层面的编程(你知道的,线程之类的)。

有什么想法可能是问题所在,我想它可能与游戏循环和更快的处理器有关。


首先,Java不是实时的;其次,通过sleep计算时间是相当不可预测的;第三,像你这样的代码(同样)也取决于CPU数量和线程如何被调度。- 研究一下Java的Future和Timer。您还可以尝试查找一些关于实时编程的文献。- 但请注意,游戏引擎有方法和手段来避免这些困难,但这并不是您的“纯Java”。 - laune
2个回答

2
关于为什么更快的CPU出现了卡顿,我猜测是因为updateAndRender(...)中的代码。很可能这个方法既更新又渲染,而你可能有多次更新,但只想跳过几次渲染。
对于游戏循环和这类时间循环,记住你的循环会“提前”和“落后”所需时间。这意味着期望你的循环“按部就班”是不切实际的期望。一旦你休眠,你就把控制权交给操作系统。操作系统可能按照请求的时间让你休眠,但很可能如果它没有更好的事情要做,它会提前唤醒你,如果它很忙,它可能会延迟唤醒你。
考虑到这一点,首先确定你已经休眠了多少个游戏“tick”并更新世界状态。然后确定是否已经休眠足够长的时间进行屏幕更新,如果还没有,就等待。如果已经休眠足够长的时间,则检查是否需要多次更新,如果是,则只进行“最后一次”更新。如果你“跳过”了太多屏幕更新(4次是一个好数字),那么就以错误退出,表示屏幕无法以你的目标速度(15fps)绘制。

你好,你的建议听起来真的很有趣。你能否再解释一下最后一段是什么意思呢?可以用一些伪代码吗?我有点难以理解它。 - bigearsman
确定游戏世界更新的最小时间步长。确定图形更新的最小时间步长。在每个循环开始时,找出你错过了多少次游戏世界更新,然后进行更新。找出你错过了多少次图形更新,然后进行零次或一次更新。这允许丢失图形帧。在更快的系统上,你可能会尝试为每个游戏世界更新绘制,导致大量绘制,浪费周期,并在图形层引起争用。这种争用可能是你看到卡顿的原因。 - Edwin Buck

1
Thread.sleep 方法本身不是一个可靠的维持帧率的方法。维持帧率的最准确的方法是在渲染开始时使用 System.currentTimeMillis() 进行测量,然后在渲染后使用循环调用 Thread.sleep(1),直到后续 System.currentTimeMillis() 的差值超过帧率阈值为止。
更多详情请参见 answer

谢谢,我会去查看的。 - bigearsman

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