Removed..

Removed…

1000 milliseconds in one second.
You want 25 frames per second.

Therefore 1000/25 = 40ms is the total time each frame that should be spent on producing & sleeping that frame.

So the time you should sleep each frame is something like:

40ms - timeSpentProducingFrame = sleepTime (provided it doesn’t go below 0).

Removed…

Not sleep(40) but sleep(40-timeSpentProducingFrame), I think this what kappa would to say.
Active rendering can help slow computer in resulting same framerate.

you have to put on a variable the time you started your iteration, then do logic and draw, take the difference from the start of iteration, then sleep (40- iterationTime) .



long startOfIteration= System.nanoTime();

//do logic
//do draw

long delay = (System.nanoTime() - startOfIteration)/1000000 - 40;

if (delay>0)
   Thread.sleep(delay);


Removed…

Don’t forget that there are still a lot of OS’s with slow clock interrupts out there, like Win XP. The accuracy of the sleep is only within +/- 15 msec, unless you do the trick to get a high speed clock mode:

http://www.java-gaming.org/index.php/topic,24311.msg206914.html#msg206914

Removed…

Setting that thread as a daemon will make it run in the background and will automatically end when the applet is closed.
The only thing you need to know about sleep(xx) is that is inaccurate without using that thread sleeping forever trick. Otherwise, you’re good to go.
For a really smooth game loop, it is best if you use a busy Thread.yield loop like this:


long now = System.nanoTime();
while(System.nanoTime()-now < sleepTime)
    Thread.yield();

This causes the game loop to be really smooth, however this hogs the CPU. For better performance with a slightly less smooth loop, use Thread.sleep(1) instead.

Removed…

Removed…

It probably is, but still doesn’t achieve 1ms accuracy. Try the same without the accuracy thread and you might even have much bigger differences. Hence the tight loop checking the actual time spend by the sleep on every iteration.

Removed…

Is this a question or have you tried it?

Why you are trying to clutter your game code with those sleep(2)
Only set sleep in one place and only if needed. There isn’t any reason for minimum sleep. Just use example what raking provided and you are safe. Don’t try to use any kind of magic here. Its just a game loop and done millions times before. Use what is already tested and proved to behave smoothly.

Removed…

I agree, your timing numbers make it look like the XP is still using its clock interrupt of about 15msec. I can think of two possible reasons that you are not showing better accuracy with your TimerAccuracyThread running.

  1. [Unlikely] Maybe this tactic only works with Win XP sp 3. My system is sp3, not 2, so I can’t say for sure it works on sp2.

(2) Maybe you are measuring your accuracy using System.currentTimeMillis(). It will remain at 15msec accuracy, even with TimerAccuracyThread running. To measure elapsed time correctly (if you are not already doing so) use System.nanoTime() instead.

Below is a class I wrote which I use to get timing metrics. The main() method will demonstrate the difference between measuring with currentTimeMillis() and nanoTime(). Try running it with and without TimerAccuracyThread.

public class TimeMetric {

	private long start, end;
	private int fpsCounter;
	
	public void fps()
	{
		// reset every second
		if (System.nanoTime() - start > 1000000000)
		{
			start = System.nanoTime();
			System.out.println("fps:" + fpsCounter);
			fpsCounter = 0;
		}
		else
		{
			fpsCounter++;
		}
	}
	
	public void peg()
	{
		start = System.nanoTime();
	}
	
	public void dur()
	{
		System.out.print("dur:"); 
		end = System.nanoTime();
		System.out.format("%.6f%n", (end - start)/1000000.0);
	}
	
	public static void main(String[] args) throws InterruptedException 
	{
		long start = 0;
		long end = 0;
		for (int i = 5; i < 100; i += 5)
		{
			System.out.print("Sleep Int: " + i + "   ");
			start = System.currentTimeMillis();
			Thread.sleep(i);
			end = System.currentTimeMillis();
			System.out.println("  difMillis: " + (end - start));
			int j = 0;
			while ( j < Math.random()* 10000) j++;
			start = System.nanoTime();
			Thread.sleep(i);
			end = System.nanoTime();
			System.out.print("                    difNanos: "); 
			System.out.format("%.1f%n", (end - start)/1000000.0);
			System.out.println();
		}
	}
}

Why so many calls to Thread.yield() O___O ?!

Dont clutter the code. Use sleep/yield only in on place inside of loop and dont put it after the draw calls. If you are doing turn based game use sleep if something with real time components then use yield.

Where you have “learn” that yield/sleep after image drawing thing. It’s just plain wrong. Computers are most efficient when they are running on full speed. Best method is then: draw fast as possible and sleep after that until next frame is needed to render.

Sama suomeksi: Renderöi mahdollisimman nopeasti ja lepuuta sitten. Älä sotke koodiasia turhilla yieldeillä render metodissa.