I am writting a simple game, and I want to cap my framerate at 60 fps without making the loop eat my cpu. How would I do this?
The simple answer is to set a java.util.Timer to fire every 17 ms and do your work in the timer event.
Here's how I did it in C++... I'm sure you can adapt it.
void capFrameRate(double fps) {
static double start = 0, diff, wait;
wait = 1 / fps;
diff = glfwGetTime() - start;
if (diff < wait) {
glfwSleep(wait - diff);
}
start = glfwGetTime();
}
Just call it with capFrameRate(60)
once per loop. It will sleep, so it doesn't waste precious cycles. glfwGetTime()
returns the time since the program started in seconds... I'm sure you can find an equivalent in Java somewhere.
What I have done is to just continue to loop through, and keep track of when I last did an animation. If it has been at least 17 ms then go through the animation sequence.
This way I could check for any user inputs, and turn musical notes on/off as needed.
But, this was in a program to help teach music to children and my application was hogging up the computer in that it was fullscreen, so it didn't play well with others.
I took the Game Loop Article that @cherouvim posted, and I took the "Best" strategy and attempted to rewrite it for a java Runnable, seems to be working for me
double interpolation = 0;
final int TICKS_PER_SECOND = 25;
final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
final int MAX_FRAMESKIP = 5;
@Override
public void run() {
double next_game_tick = System.currentTimeMillis();
int loops;
while (true) {
loops = 0;
while (System.currentTimeMillis() > next_game_tick
&& loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
interpolation = (System.currentTimeMillis() + SKIP_TICKS - next_game_tick
/ (double) SKIP_TICKS);
display_game(interpolation);
}
}