Yeah, a new game loop seems to be in order… Thanks for the help guys. Ultroman, which would you recommend? Fixed or variable time step?
You have a lot of stuff about unprocessedSeconds and ticking. It seems like a mix of methods, and it gets very confusing.
It seems weird to me that you’d ever get deltatimings of 1 and 5. I’m running my game at 60fps using a variable timestep loop, and my deltatimings are usually around 16.0. I only update each frame, because I don’t need any more than that. If I need to do any collision-detection more precisely (so bullets don’t go through something in a single frame), I simply divide the deltaTime by a factor in my bullet collision-code, and check the progression and collisions for the bullet each iteration of the divided time.
This run-through of gameloops may help you, although the fixed timestep implementation is a bit confusing. I’d go with the variable timestep loop, but read through that article, and see which one is the best for your situation.
This is what I use:
private volatile boolean running = false;
private int desiredFPS = 60;
private int fps = 0;
private int frames = 0;
private long totalTime = 0L;
private long sleepTime = 0L;
private long deltaTime = 0L;
private long lastUpdateTime = 0L;
private long currentUpdateTime = 0L;
private long endLoopTime = 0L;
private long maxDelta = 17 * (long)1e6, desiredDelta = Math.round((double)1000000000L / desiredFPS);
public void run() {
currentUpdateTime = System.nanoTime(); // game-loop timing variable
while (running) {
currentUpdateTime = System.nanoTime();
// I've separated the FPS-calculations for readability purposes.
updateTimersForFPScounter();
deltaTime = currentUpdateTime - lastUpdateTime;
lastUpdateTime = currentUpdateTime;
/* Update all objects. If deltaTime is above the maxDelta, we keep running it through
* with maxDelta, until the remaining deltaTime is less than maxDelta.
* Then we run it through for the last time, with the remaining deltaTime,
* and we should be exiting the loop after that. This makes sure our gameLogic never
* gets passed a deltaTime it cannot handle. So all collisions are checked each time
* we go through the loop. Good for avoiding anomalies in gamelogic calculations.
*/
while(deltaTime > 0) {
long delta = deltaTime > maxDelta ? maxDelta : deltaTime;
updateGameLogic(delta);
deltaTime -= delta;
}
// This construction is taken from some of Ra4king's code (most of this is, really).
// Ignore this if you're not using Java2D, and just draw all your things here instead.
do{
do{
// Get a graphics2D object to draw with.
Graphics2D g = (Graphics2D)s.getBufferStrategy().getDrawGraphics();
draw(g); // draws whatever you'd like
//Dispose of graphics context
g.dispose();
}while(s.getBufferStrategy().contentsRestored());
s.getBufferStrategy().show();
}while(s.getBufferStrategy().contentsLost());
// Find out the amount of time we should sleep after this update, to hit 60fps.
endLoopTime = System.nanoTime();
sleepTime = desiredDelta - (endLoopTime - currentUpdateTime);
long diff;
if(sleepTime>0){
while((diff = System.nanoTime()-endLoopTime) < getSleepTime()) {
if(diff < getSleepTime()*0.8)
try { Thread.sleep(1); } catch(Exception exc) {}
else
Thread.yield();
}
}
}
// These last lines make sure that if my game is currently in fullscreen mode, I reset the screen
// and close the program completely. This is where you'd normally unload everything, and shut down,
// as we have just exited the while(running) loop.
if(!s.isWindowedMode())s.restoreScreen();
System.exit(-1);
}
private void updateTimersForFPScounter() {
totalTime += currentUpdateTime - lastUpdateTime;
// count up frames per second...
frames++;
if( totalTime >= 1000000000) {
totalTime = 0;
setFps(frames);
frames = 0;
}
}
Yeah, that’s A LOT better than the monstrosity that I posted, do you mind if I use it?
What is the problem with that? Wouldn’t it be more of a problem if you set lastTime to 0 and then have uncontrollable delta in the first frame? Because you never know the relative starting point of the time measuring of nanotime().
I prefer having no movement or change in the first frame. Why should that be a problem at all?
Not at all
If the timings of lastTime and the deltaTime you use later to update before the first frame, you will get a little bit of remainder from their differences, which I would define as an abnormal deltaTime for a frame. Better to ensure that it updates a correct amount of time.