Java: I just need to make a bloody gameloop that does not eat cpu ._.

12 posts

Flag Post

I want to make a game in Java…

For days I’ve been struggling with the gameloop.

The fps would be really uneven and unexpected. It turned out Thread.sleep is inaccurate (+/- 10 ms) and that was the problem.

So I made a new gameloop where I only call Thread.sleep(1) when there are more than 5 ms remaining of the frame.

But everyone says it uses 7% of their cpu. …. I just want to start with the fucking game already.

package plong;
public abstract class GameLoop {
	
	public boolean running = false;
	public int targetFps = 60;
	
	
	public void run()
	{
		running = true;
		
		//
		final long OPTIMAL_DURATION = 1000000000 / targetFps; // Expected frame duration in nano seconds
		
		long startTime = 0;
		
		// --- 
		while (running)
		{
			System.out.println("Frame duration: " + (System.nanoTime() - startTime) / 1000000.0);
			startTime = System.nanoTime();
			
			//// Update \\\\
			
			update();
			// Sleep if any milliseconds available \\
			while (System.nanoTime() - startTime <= OPTIMAL_DURATION - 4000000) { // 5ms
				System.out.println("SLEEP");
				try { Thread.sleep(1); } catch (Exception e) {}
			}
			
			// Keep busy waiting for the rest of the time
			while (System.nanoTime() - startTime < OPTIMAL_DURATION) {
				Thread.yield();
			}
		}
	}

	
	/**
	 * To be overridden; This function gets called [targetFps] times per second.
	 */
	protected abstract void update();
}

Is there any way to make a game loop in Java that is accurate and does not eat CPU? (Accurate as in does not suddenly decide to have a constant 46 fps………….)

 
Flag Post

What is eatting your CPU is the quantity of unnecessary loops you’re doing…

You want 60fps right?

60fps is approximately 1 frame in 17 milliseconds ((1 / 60) * 1000)

So do it:


while(running){
//what will happen in each frame
Thread.sleep(17);
}

I suggest you to start using Flash, because I’ve tryed to use Java to make games and is too difficult comparing to Flash
Programming in Java is much better then Flash, but making games, Flash is better…

The reason is that Flash was made to make animations, it has a lot of stuffs that helps to create games and animations, and Java was made to program easily, it has a lot of API’s and logics that helps in programming.

 
Flag Post

That is assuming that whatever happens each frame takes less than 1 ms. You probably should measure how long the frame takes and subtract that from 17.

Also, @hurricane ErlendHL has used Flash before. ;) Check his post history.

 
Flag Post
Originally posted by UnknownGuardian:

That is assuming that whatever happens each frame takes less than 1 ms. You probably should measure how long the frame takes and subtract that from 17.

Also, @hurricane ErlendHL has used Flash before. ;) Check his post history.

Yes you are right…

So @ErlendHL, if you want to do it in Java, go ahead!

To make it easy, I suggest you to make Classes that deal with some repetitive actions automatically, then you just need to call one or more specific functions to make an action. For example a Class Drag with a function execute that receives an Object and makes this object draggable…

 
Flag Post

I did what UnknownGuardian said; slept for ((OPTIMAL_DURATION – frameDuration) / 1000000) ms, OPTIMAL_DURATION being 16666666.666… nanoseconds per frame, and frameDuration being the duration that has already elapsed in the frame.

but

Originally posted by ErlendHL:

The fps would be really uneven and unexpected. It turned out Thread.sleep is inaccurate (+/- 10 ms) and that was the problem.

On my stationary computer at home, the actual sleep time can go to + 10 ms more than the expected sleep time, and it can also be unexpectedly low. On my school computer, the sleep time is mostly less than the expected sleep time but can also go above. So Thread.sleep() apparently uses a timer in the os or the hardware, that is not intended to be accurate at all. Since it differs so much from pc to pc, I find it pretty hard to rely on Thread.sleep for the game loop. Especially in physics simulations, which I will start with soon.

 
Flag Post

Can you use a timer? Something kind of like this?

 
Flag Post
Originally posted by feartehstickman:

Can you use a timer? Something kind of like this?

I did a test with timer.scheduleAtFixedRate and it seems to be just as uneven, but it also seems to regulate itself: http://hastebin.com/dikifowije.vbs That is on my school computer. It does not use much cpu so I might just use this.

 
Flag Post

Thread.sleep is not a good way to do timekeeping. What it does is puts the thread to sleep for at least as long as you ask – if the system is heavily loaded, it could be a lot (indefinitely) longer. (It should never be shorter, my guess is you’re tripping over issues with the timer you’re trying to use to see how long it takes there; the default timer is only accurate to about 15ms.)

Did you try the paint/invalidate loop I suggested before? That will use CPU but only within the context of the OS’s message queue, so you won’t overload anything.

 
Flag Post

On my school pc I can get far less sleep time than expected.

I don’t see any suggestion from you in this thread though :o

Anyway I will just stick to timer.scheduleAtFixedRate for now, it works pretty well.

 
Flag Post
Originally posted by ErlendHL:

On my school pc I can get far less sleep time than expected.

I don’t see any suggestion from you in this thread though :o

Anyway I will just stick to timer.scheduleAtFixedRate for now, it works pretty well.

http://www.kongregate.com/forums/4-game-programming/topics/329369-java-displaying-game-graphics?page=1#posts-6917408 I think.
 
Flag Post

o.o The post seems to be hidden on this computer, but I could see it my school computer earlier today….

 
Flag Post
Originally posted by ErlendHL:

o.o The post seems to be hidden on this computer, but I could see it my school computer earlier today….

That post is not hidden. I’ve quoted it here just in case you have issues:

Originally posted by BobJanova:

It isn’t the standard application model, but you can simulate a game loop pretty well in Java (and .Net) by hooking your game logic into paint (or paintComponent or whatever Swing uses; I haven’t done Java UI since about 1996 with the AWT) and calling invalidate() at the bottom of your paint handler to put it back in the queue.