I implemented my game-loop as described in deWiTTER's article, using the last approach with an unlimited FPS and a constant game-speed.
My problem is, that the unlimited FPS cranks up my CPU usage to nearly 100%. I understand that this is desired (as the hardware does as much as it can), but for my game, it's not really necessary (it's pretty simple). So I'd like to limit the FPS to some upper bound.
Consider my game-loop:
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);
}
How would I implement a maximum FPS?
If i implement the repaint the way I implemented the update (or use a sleep instead of "do-nothing-cycles"), then the FPS is locked, right? That is not what I want. I want the game to be able to work with lower FPS (just as it does now), but limit the FPS to a maximum of, say 250.
Answer
Store the last time you rendered a frame, and if it hasn't been enough time, Sleep().
Note that Sleep() can sometimes result in your program not waking up when it should, giving you a framerate stutter - test it pretty carefully. In my experience most modern OSes will timeslice frequently enough that this won't be an issue except in fast-paced first-person-shooters.
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);
}
No comments:
Post a Comment