Search code examples
javarenderingframe-rate

How to make a rendering loop run at a consistent rate?


I've written a program with moving animated sprites based on user input that all takes place in a while(true) loop. Up until now the only way I've been timing the loop is by having a sleep(20) at the end of each run through the loop. I have noticed this effects the physics of my sprites negatively because my formula for calculating gravity is velocity = velocity + GRAVITY * Elapsed-Time and because the loop isn't running at a consistent rate the effect of gravity is not consistent either. Is there a way to keep the loop running consistently or better way of timing it so it actually runs on a schedule?


Solution

  • First, determine how long you want your frames to last. If you want 30 fps, then you'll have

    final long frameDuration = 1000 / 30;
    

    Next, when you start rendering, store the time, like so

    final long then = System.currentTimeMillis();
    render(); // surely it's more than this but you get the idea
    final long now = System.currentTimeMillis();
    
    final long actualDuration = now - then;
    final long sleepDuration = frameDuration - actualDuration;
    
    if(sleepDuration > 0) {
        sleep(sleepDuration);
    } else {
        throw new FrameTooLongException();
    }