Game loop not accurate. How can I make a better one ?

This game loop that I have implemented is not constant. I want my program to run at 60 frames per second. Basically I need to make the Thread sleep for 17 milliseconds after each frame, but sometimes it sleeps more that 17 milliseconds, this makes my game jittery. What should I do to make a more efficient game loop?

public class GamePanel extends JPanel implements Runnable {

	
	@Override
	public void run() {
		currentTime = System.currentTimeMillis();
		prevTime = currentTime;
		while(true) {
			repaint();
			upd();
			try {
				Thread.sleep(17);
			} catch(InterruptedException e) {
				e.printStackTrace();
			}
			prevTime = currentTime;
			currentTime = System.currentTimeMillis();
			delta = currentTime - prevTime;
			System.out.println(delta);
		}
	}
}

Check out this guide! http://www.java-gaming.org/index.php?topic=24220.0 :slight_smile:

actually it is okay, but you have to factor the delta value in your update() method.

just divide delta through 17 and you have your update factor.
For example:

player speed is 10. if delta is 17 (optimum) you calc:

player.position += 10 * 17 / 17

so plus ten. if your game sleeps longer for example delta = 34,
delta / 17 is 2 and your player would move twice as fast in this frame.

Actually it is not ok.

When it says
Thread.sleep(17)

you are assuming you render takes 0ms - which is most probably not correct.

The sleep should be 17 - time to render. So you should tke note on how long it takes to render stuff and reduce that from the sleep time afterwards.

That just makes it more complicated.
You already have your delta calculated , just check to see if the delta >= 60/1000000000 , this is if you are using nano_time(); this will render at 60 - 58 FPS just modify the value at will.

a good and solid timer would be nice to have … but it’s not gonna happen :frowning:

using [icode]Thread.sleep()[/icode] is ok, using [icode]Thread.yield()[/icode] is not that good … but helps with “jerky” loops.

whatever you do … try using [icode]Thread.speep(1)[/icode] and then try to find a threshold when to use [icode]Thread.yield()[/icode] to skip the last tiny bit of time to keep the loop stable.

afaik that’s the only way to get it to do someting useful.

You can take a look at what LWJGL uses: https://github.com/LWJGL/lwjgl/blob/master/src/java/org/lwjgl/opengl/Sync.java