Author Topic: animation loop  (Read 4537 times)

Offline raft

  • quad
  • ******
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
animation loop
« on: March 21, 2006, 04:22:36 am »
well, first of all this is not a jPCT question, it's about the strange behaviour of my animation loop on some rare machines. i have no idea why and when that happens, maybe you may have

i've taken the animation loop below from a book about Java games and slightly modified

as you can see, the main idea is to keep updates per second constant (as much as the desired fps = 1 / period). it works reasonably well on most machines (including my slow one) but on some rare ones, updates per second increases unexpectedly up to 2-3 times.  

i've no idea how that can happen ? i can only blame window's system clock granularity or sleep time inaccuracies (even with sleep time inaccuracies that loop shouldnt expected to run faster ??)

so do you have any ideas why this may happen ?
thx

edit: the mentioned book by Andrew Davison can be found online at http://fivedots.coe.psu.ac.th/~ad/jg/

Code: [Select]

            long beforeTime, afterTime, timeDiff, sleepTime;
            long overSleepTime = 0;
            int noDelays = 0;
            long excess = 0;
           
            running = true;
           
            while(running) {
                try {
                    beforeTime = System.nanoTime();
                    gameUpdate();
                    if (! paused)
                        gameRender();
                   
                    afterTime = System.nanoTime();
                    timeDiff = afterTime - beforeTime;
                    sleepTime = (period - timeDiff) - overSleepTime;
                   
                    if (sleepTime > 0) { // some time left in this cycle
                        try {
                            Thread.sleep(sleepTime/1000000L); // nano -> ms
                        } catch(InterruptedException ex) {}
                       
                        overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
                       
                    } else { // sleepTime <= 0; frame took longer than period
                        excess -= sleepTime; // store excess time value
                        overSleepTime = 0L;
                       
                        if (++noDelays >= KConfig.noDelaysPerYield) {
                            Thread.yield(); // give another thread a chance to run
                            noDelays = 0;
                        }
                    } // if-else (sleepTime > 0)
                   
                    /* If rendering is taking too long, update the game state without rendering it, to get the updates/sec nearer to the required FPS. */
                    int skips = 0;
                    while (running && (excess > period) && (skips < KConfig.maxFrameSkips)) {
                        excess -= period;
                        skips++;
                        gameUpdate(); // update state but don't render
                    }
                   
                } catch (Throwable t) {
                    logger.warning("exception in timer thread {0}", t);
                }
            } // while running


Code: [Select]
r a f t

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
animation loop
« Reply #1 on: March 21, 2006, 05:35:32 pm »
sleep() in Windows has a granularity of 10ms IIRC...that's for single cpu/core machines. On dual core (and even hyper threading ones), it's 15ms. Relying on sleep alone for timing is not a good idea IMHO.

Offline raft

  • quad
  • ******
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
animation loop
« Reply #2 on: March 21, 2006, 09:53:51 pm »
i see. so is there any alternative to sleep for fixed time step approach ? or do you mean making all things tickable is the only way ?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
animation loop
« Reply #3 on: March 22, 2006, 06:45:56 pm »
Quote from: "raft"
or do you mean making all things tickable is the only way ?
That's what i'm doing now after i've been through all these other options before, but that doesn't mean that it's the only valid solution. It's just the only one i have to offer.

Offline raft

  • quad
  • ******
  • Posts: 1993
    • View Profile
    • http://www.aptalkarga.com
animation loop
« Reply #4 on: March 22, 2006, 10:58:21 pm »
considering my experience how much it differs between a timer based approach and animation loop, i agree with you: depending on sleep and other os timing measures is not good idea. i put it in my todo list, although not that urgent (since requires a lot of work :/)

if you dont run cpu to its limits everything is working fine, but the more you load the cpu the stranger the whole system behaves.

i also find it strange that there are so many articles, books etc suggesting fixed time step approach. it obviously eases some calculations but..

btw, i still cant figure out how on some machines that loop can run 2-3 times faster. i cant imagine how clock granularity and sleep inaccuracy may result this continuosly (it's not for a second or so, it just runs fast ??)

Code: [Select]
r a f t