Java2D 游戏随机卡顿。我究竟做错了啥?
Posted
技术标签:
【中文标题】Java2D 游戏随机卡顿。我究竟做错了啥?【英文标题】:Java2D game stutters randomly. What am I doing wrong?Java2D 游戏随机卡顿。我究竟做错了什么? 【发布时间】:2018-02-01 16:49:02 【问题描述】:我目前正在使用 Swing 组件开发 2D 游戏。 每次我运行我的游戏时,它都会在某些时候随机出现口吃。这是我的游戏循环代码:
public class FixedTSGameLoop implements Runnable
private MapPanel _gamePanel;
public FixedTSGameLoop(MapPanel panel)
this._gamePanel = panel;
@Override
public void run()
long lastTime = System.nanoTime(), now;
double amountOfTicks = 60.0;
double amountOfRenders = 120.0;
double nsTick = 1000000000 / amountOfTicks;
double nsRender = 1000000000 / amountOfRenders;
double deltaTick = 0;
double deltaRender = 0;
while (this._gamePanel.isRunning())
now = System.nanoTime();
deltaTick += (now - lastTime) / nsTick;
deltaRender += (now - lastTime) / nsRender;
lastTime = now;
while (deltaTick >= 1)
tick();
deltaTick--;
while (deltaRender >= 1)
render();
deltaRender--;
private void tick()
/**
* Logic goes here:
*/
this._gamePanel.setLogic();
private void render()
/**
* Rendering the map panel
*/
this._gamePanel.repaint();
我多次尝试省略某些代码部分,认为它们会导致延迟,但我没有发现任何特别导致它的原因,所以我认为问题出在我的游戏循环机制上。 感谢您的帮助!
【问题讨论】:
从另一个线程对 Swing 方法(包括repaint
)的任何调用都需要在 EDT 上使用SwingUtilities.invokeLater
方法完成。
嗯,你能给我一个关于我的代码的例子吗?游戏循环的其他方面还好吗?
SwingUtilities.invokeLater( () -> _gamePanel.repaint() );
为其中之一。您可能还需要对 _gamePanel.setLogic();
执行相同的操作。
同样的问题依然存在...
Each time I run my game it stutters randomly at some points.
- 你有一个不断执行的 while 循环。游戏应该在某个时间间隔进行,以便 CPU 有机会休息。所以,你应该使用Swing Timer 来安排你想要的时间间隔玩游戏。
【参考方案1】:
您的游戏循环必须包含“Thread.sleep”,以便在尊重您的目标 FPS 所需的时间内休眠。
主循环应该包含 1 个 tick() 和 1 个 render()。
您当前的实现正在淹没绘制管理器,当底层缓冲区已满以及垃圾收集器将完成其工作时会出现减速。
【讨论】:
但是代码只有在“deltaRender”变量达到1的值时才调用render方法,这意味着距离上次调用已经过去了1000/120毫秒(与逻辑设置相同,但为1000/60 毫秒)。 当然,但你的主进程却在 100% 消耗 CPU 核心。使用 sleep()。 需要更多详细信息?见gameprogrammingpatterns.com/game-loop.html。 我明白了。我只是在循环结束时调用了 Thread.Sleep(1),它现在就像一个魅力。谢谢!【参考方案2】:虽然您将渲染和逻辑拆分为两种不同的方法很好,但问题在于它们存在于同一个线程中。
减少延迟需要做的是将它们放在单独的线程中。渲染线程将从逻辑线程请求当前状态的快照(以防止并发修改)并渲染该快照。
现在,如果一个渲染耗时过长,或者一个逻辑步骤耗时过长,则另一项检查将不得不等待它完成才能开始工作。
【讨论】:
以上是关于Java2D 游戏随机卡顿。我究竟做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章