I am writing a simple bouncing balls animation, where the balls bounce off the walls and the other balls. I am following the worm example from "Killer Game Programming in Java". Here is my main game loop:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public void run() { long beforeTime, afterTime, timeDiff, sleepTime; long overSleepTime = 0L; int noDelays = 0; long excess = 0L; Thread.currentThread().setPriority(Thread.MAX_PRIORITY); isRunning = true; gameStartTime = System.nanoTime(); prevStatsTime = gameStartTime; beforeTime = gameStartTime; while (isRunning) { nextFrame(period/1000000L); updateDisplay(); afterTime = System.nanoTime(); timeDiff = afterTime - beforeTime; sleepTime = (period - timeDiff) - overSleepTime; if (sleepTime > 0) { try { Thread.sleep(sleepTime / 1000000L ); } catch (InterruptedException ex) { } overSleepTime = (System.nanoTime() - afterTime) - sleepTime; } else { excess -= sleepTime; overSleepTime = 0L; if (++noDelays >= NO_DELAYS_PER_YIELD) { Thread.yield(); noDelays = 0; } } beforeTime = System.nanoTime(); int skips = 0; while ((excess > period) && (skips < MAX_FRAME_SKIPS)) { excess -= period; nextFrame(period/1000000L); skips++; } framesSkipped += skips; updateStats(); } } |
And here is my the code for updating the animation state:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public void nextFrame(double t) { if (isPaused) return; for (int i = 0; i < balls.length; i++) { t = Math.min(t, balls[i].testWallCollision(t)); } List<Collision> collisions = new LinkedList<Collision>(); Ball a, b; for (int i = 0; i < balls.length; i++) { a = balls[i]; for (int j = i+1; j < balls.length; j++) { b = balls[j]; t = Math.min(t, a.testBallCollision(b, t, collisions)); } } for (int i = 0; i < balls.length; i++) { balls[i].move(t); } for (Collision c : collisions) { if (c.t == t) { c.handle(); } else { break; } } } |
My problem is that I want the frame to update according to how much time has passed since the last frame. At the moment I just assign t to the period (converting to ms) . Should I pass in timeDiff from the last loop instead (for the first nextFrame call that is rendered)?
Also multiple collisions may have occured since the last frame. At the moment I update the state to the time of first collision (or t if no collisions occured). I should continue to handle collision until no collisions are left for the frame. However will this not likely mean the nextFrame() method takes too much CPU time before we paint the next frame? How should I be handling this?