Saturday, April 28, 2018

game loop - Implement an upper FPS limit in the gameloop



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

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...