1
\$\begingroup\$

I want to pass the time elapsed to the update() method as this would make easy to implement the animations and time related concepts.

Here's my game-loop.

public void gameLoop(){
    boolean running = true;

    long gameTime = getCurrentTime();

    long elapsedTime = 0;
    long lastUpdateTime = 0;

    int loops;

    while (running){

        loops = 0;

        while(getCurrentTime()>gameTime && loops<Global.MAX_FRAMESKIP){
            elapsedTime = getCurrentTime() - lastUpdateTime;
            lastUpdateTime = getCurrentTime();

            update(elapsedTime);

            gameTime += SKIP_STEPS;
            loops++;
        }

        displayGame();
    }
}

getCurrentTime() method

public long getCurrentTime(){
    return (System.nanoTime()/1000000);
}

update() method

long time = 0;

public void update(long elapsedTime){
    time += elapsedTime;
    if (time>=1000){
        System.out.println("A second elapsed");
        time -= 1000;
    }
}

But this is printing the message for 3 seconds.

Thanks.

\$\endgroup\$
5
  • \$\begingroup\$ Also, this: elapsedTime = getCurrentTime() - lastUpdateTime; is going to produce something extreme in the first loop. Also, are the update() method, the 'time' variable, and the gameLoop() methods in the same class? Also, what are the values of SKIP_STEPS and MAX_FRAMESKIP? \$\endgroup\$
    – Marton
    Commented Nov 2, 2012 at 8:24
  • \$\begingroup\$ SKIP_STEPS = 30 and MAX_FRAMESKIP = 10 \$\endgroup\$ Commented Nov 2, 2012 at 8:35
  • \$\begingroup\$ Are you sure that this code is printing the message every 3 seconds? Because I think this would keep printing the message 33 times per second, almost forever. Initialize the lastUpdateTime to getCurrentTime() instead of 0. \$\endgroup\$
    – Marton
    Commented Nov 2, 2012 at 8:50
  • \$\begingroup\$ @MarcoMartinelli I also recommended the currentTimeMillis(), but then deleted my comment because of this: stackoverflow.com/questions/1770010/… \$\endgroup\$
    – Marton
    Commented Nov 2, 2012 at 8:53
  • \$\begingroup\$ @Marton thank you, I didn't know that. I've deleted my comment. \$\endgroup\$
    – pinco
    Commented Nov 2, 2012 at 8:58

1 Answer 1

4
\$\begingroup\$

First, you should avoid calling getCurrentTime() multiple times per loop. You will potentially be getting different values at different times. Call it once at the start of the loop and use that value as the current time for the rest of the loop. Also, you are advancing gameTime by a fixed amount each time rather than the length of the frame, you are sort of mixing a fixed step and variable length frame concept here. To have variable length frames, you probably want something more like:

long elapsedTime = 0;
long lastUpdateTime = getCurrentTime();
long gameTime = 0;

while (running){
    gameTime = getCurrentTime();
    elapsedTime = lastUpdateTime - gameTime;

    // This is where you can apply a minimum frame time if you want, at the
    // very least, you should make sure elapsedTime > 0, since
    // you don't want to run 0 length frames
    if (elapsedTime < Global.MIN_FRAME_LENGTH)
        continue;

    update(elapsedTime);

    displayGame();

    lastUpdateTime = gameTime;
}

That inner loop is only necessary if you want to have a maximum frame time, in which case you could do something like:

long gameTime = getCurrentTime();

long elapsedTime = 0;
long lastUpdateTime = getCurrentTime();
long currentTime = lastUpdateTime;
long frameTime = 0;

while (running){

    currentTime = getCurrentTime();
    elapsedTime = lastUpdateTime - currentTime;

    if (elapsedTime < Global.MIN_FRAME_LENGTH)
        continue;

    while (elapsedTime > 0) {
        frameTime = elapsedTime;
        if (frameTime > Global.MAX_FRAME_LENGTH)
            frameTime = Global.MAX_FRAME_LENGTH;

        update(frameTime);
        elapsedTime -= frameTime;
    }

    displayGame();

    lastUpdateTime = currentTime;
}
\$\endgroup\$
3
  • \$\begingroup\$ Stylistic options: The majority of game engines I've worked with pass the elapsed time as seconds in a float. Some pass milliseconds in a uint. Unity3D uses a seconds float but stores it in a singleton rather than pass it around. All valid options. \$\endgroup\$
    – tenpn
    Commented Nov 2, 2012 at 10:15
  • \$\begingroup\$ I'm using the one's specified at Dewitters article - koonsolo.com/news/dewitters-gameloop \$\endgroup\$ Commented Nov 2, 2012 at 10:28
  • \$\begingroup\$ @Sri Harsha Chilakapati the only good part in that article is the comment from Christian Köhler at the end. \$\endgroup\$ Commented Nov 2, 2012 at 13:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .