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

时间:2014-11-08 16:35:59

标签: java cpu-usage game-loop

我尝试编写自己的游戏循环。但是cpu的使用率太高了。它约占25%。 我的问题可能是没有Thread.sleep。但我不想使用它,因为它应该不是很准确。计算下一帧也需要10 ms。

我的代码是这样做的:
1:重新粉刷窗口(' fenster'是德语窗口)
2:读出毫秒
3:设置下一帧 我想要50 fps。因此程序需要每帧等待1000/50 = 20 ms。
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;

            }
        }

2 个答案:

答案 0 :(得分:4)

为什么Thread.sleep不如你的代码准确?你测试过它并发现它不准确吗? 如果您不想睡20分钟,请将睡眠分成几个部分,调整最终睡眠,使总时间为20毫秒。

这样的事情:(我是C#dev,所以你可能需要稍微调整一下代码)

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。如果重绘时间超过18毫秒,此代码将中断,因此请添加一些测试。

另一个澄清的编辑: 你的画框需要10毫秒的时间来画画。要达到50 fps,每帧总共需要20ms,即如果重绘时间为11ms,则在绘制下一帧之前必须睡9ms。

首先分配

startTime,然后重新分配,占用appx 10ms。 重绘后,我们再次检查系统计时器,并减去开始时间以获得经过的时间。 然后我们从20中减去这个数字,得到ms的数量直到下次重绘。

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

所有这些加起来可达20毫秒,您可以渲染下一帧。

答案 1 :(得分:0)

如此多的嵌套循环会影响性能

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) {

...

你必须每20分钟检查一次差异,并尝试每隔一秒左右纠正错误......如:

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