Java:游戏循环 - CPU使用率过高

问题描述:

我尝试编写自己的游戏循环。但CPU使用率太高。这大概是25%。 我的问题可能是没有Thread.sleep。但我不想用它,因为它应该不是很准确。另外计算下一帧可能需要10毫秒。Java:游戏循环 - CPU使用率过高

我的代码是这样做的:
1:重新绘制窗口(“芬斯特”是在德国窗口)
2:读出毫秒
3:设置下一帧
我想有50 fps的。所以程序每帧需要等待1000/50 = 20毫秒。
4:计算的时间和设置下一帧

 // GameSchleife 
     while (true) { 

      // First repaint 
      fenster.repaint(); 

      // Before calculating the next frame, capture the time 
      long a = System.currentTimeMillis(); 
      long b = a; 

      // Calculate the next frame 
      fenster.Update(); 

      // Wait for 20 ms (50 frames in a second) 
      for (int time = 0; time < 20;) { 

       // Wait for at least 1 ms 
       while (a == b) { 
        a = System.currentTimeMillis(); 
       } 

       // Difference from a and b 
       time = time + ((int) (a - b)); 

       // 
       a = System.currentTimeMillis(); 
       b = a; 

      } 
     } 
+0

那么,什么是你的题? – 2014-11-08 16:48:27

后的差额为什么了Thread.Sleep比你的代码不准确的?你有没有测试过它,发现它不准确? 如果你不想睡20ms,将睡眠分成几部分,调整最后的睡眠时间,使总时间为20ms。

事情是这样的:(我是C#开发,所以你可能需要调整代码中使用一点)

while (true) 
{ 
    long startTime = System.currentTimeMillis(); 

    fenster.repaint(); 

    long remaining= 20 - (System.currentTimeMillis() - startTime); 
    Thread.sleep(remaining - 2); // adds up to 18 ms since start if repaint took 10ms 

    remaining= 20 - (System.currentTimeMillis() - startTime); 
    Thread.sleep(remaining); // should be 1-2ms 
} 

你现在会杀死在任何时间任何笔记本电脑电池的代码,并可能给予你其他的加热问题。

编辑: 添加fenster.repaint()。还修复了代码,以便重绘+等待总计20ms。如果重绘时间超过18ms,此代码将会中断,因此请添加一些测试。

另一个编辑澄清: 您的框架需要10ms来绘制。要达到50 fps,每帧总共有20ms,即如果重新绘制了11ms,则在绘制下一帧之前,您必须睡眠9ms。

startTime先分配,然后重新绘制,取appx 10ms。 重新绘制后,我们再次检查系统计时器,并减去开始时间以获得流逝的时间。 然后我们从20中减去这个数字,得到毫秒数,直到下一次重绘。

然后我们进入睡眠状态,但是在系统计时器不准确的情况下,减去2ms有一点余量。我们再次重新计算剩余时间(1-2ms)并进入另一个短暂的睡眠。

所有这些都会增加到20ms,并且您可以渲染下一帧。

+0

嗯...我不明白你的代码?为什么不在开始时打(20)? 我没有测试过它。 – LittleSatan 2014-11-08 16:59:25

+0

刚刚添加了一些额外的代码,它有帮助吗? – EventHorizon 2014-11-08 17:00:17

+0

哦是的,它的工作原理:3,但我增加了一个 如果(剩余> = 2)Thread.sleep(剩余 - 2); }所以它不会崩溃。 – LittleSatan 2014-11-08 18:08:12

这么多的嵌套循环影响性能

while (true) { 
... 

// Wait for 20 ms (50 frames in a second) 
for (int time = 0; time < 20;) { 

// Wait for at least 1 ms 
while (a == b) { 

... 

你必须检查每个差异20ms的,并试图纠正错误每一秒左右......这样的:

while (true) { 
    if (((int) System.currentTimeMillis() % 20) == 0) { 
     fenster.repaint(); 
     // Calculate the next frame 
     fenster.Update(); 
    } 
}