在gameloop中实现较高的FPS限制

我按照deWiTTER的文章中所描述的那样实现了我的游戏循环,使用最后一个无限FPS和恒定游戏速度的方法。

我的问题是,无限的FPS使我的CPU使用率几乎达到 100%。 我明白,这是所需要的(因为硬件尽可能多),但对于我的游戏来说,这并不是必要的(这很简单)。 所以我想把FPS限制在一些上限。

考虑我的游戏循环:

private static final int UPDATES_PER_SECOND = 25; private static final int WAIT_TICKS = 1000 / UPDATES_PER_SECOND; private static final int MAX_FRAMESKIP = 5; long next_update = System.currentTimeMillis(); int frames_skipped; float interpolation; // Start the loop: while (isRunning){ // Update game: frames_skipped = 0; while (System.currentTimeMillis() > next_update && frames_skipped < MAX_FRAMESKIP){ // Update input, move objects, do collision detection... // Schedule next update: next_update += WAIT_TICKS; frames_skipped++; } // Calculate interpolation for smooth animation between states: interpolation = ((float)(System.currentTimeMillis() + WAIT_TICKS - next_update)) / ((float)WAIT_TICKS); // Render-events: repaint(interpolation); } 

我将如何实现最大的FPS?

如果我实现重新绘制的方式,我实现了更新(或使用睡眠,而不是“无所事事的周期”),那么FPS被locking对吧?不是我想要的。 我希望游戏能够使用更低的FPS(就像现在这样),但是将FPS限制在最大值,比如250。

存储上一次渲染帧的时间,如果时间不够 ,则使用Sleep()。

请注意,Sleep()有时会导致您的程序不能在应该唤醒的时候给您提供一个帧速率 – 对它进行非常仔细的testing。 根据我的经验,大多数现代操作系统都会经常出现这样的情况,除了快节奏的第一人称射击游戏之外,这不会成为一个问题。

 private static final int UPDATES_PER_SECOND = 25; private static final int WAIT_TICKS = 1000 / UPDATES_PER_SECOND; private static final int MAX_FRAMESKIP = 5; long next_update = System.currentTimeMillis(); /////// NEW CODE BEGIN private static final int MAX_UPDATES_PER_SECOND = 60; private static final int MIN_WAIT_TICKS = 1000 / MAX_UPDATES_PER_SECOND; long last_update = System.currentTimeMillis(); /////// NEW CODE END int frames_skipped; float interpolation; // Start the loop: while (isRunning){ /////// NEW CODE BEGIN // Delay if needed while (System.currentTimeMillis() < last_update + MIN_WAIT_TICKS){ System.Sleep(0); // I don't know C# so this is a guess, but there will be some equivalent function somewhere } last_update = System.currentTimeMillis(); /////// NEW CODE END // Update game: frames_skipped = 0; while (System.currentTimeMillis() > next_update && frames_skipped < MAX_FRAMESKIP){ // Update input, move objects, do collision detection... // Schedule next update: next_update += WAIT_TICKS; frames_skipped++; } // Calculate interpolation for smooth animation between states: interpolation = ((float)(System.currentTimeMillis() + WAIT_TICKS - next_update)) / ((float)WAIT_TICKS); // Render-events: repaint(interpolation); }