10
\$\begingroup\$

I am new to Java game programming, but the more I read the more I'm confused, because I've seen several different approaches to make a game loop: 1. The standard approach, that uses the Timer class (seems to be less precise). 2. The more precise approach that uses System.nanoTime. 3. A simple approach that uses scheduleAtFixedRate.

Which one should generally be preferred and where are the advantages/disadvantages of each approach? Thanks in advance for any info.

\$\endgroup\$
0

2 Answers 2

7
\$\begingroup\$

For a basic game loop, you'd run a while loop, within which you'd get the time using nanoTime(), determine how much time has passed since the last frame, then update your gamestate and render.

Using http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29 , you can poll for the elapsed time. Basically...

public static void main(String [ ] args)
{
    long current_frame_time = system.nanoTime();
    long last_frame_time = current_frame_time;

    while(gameIsRunning)
    {
        last_frame_time = current_frame_time;
        current_frame_time = system.nanoTime();

        long timeTaken = current_frame_time - last_frame_time;

        //update and render game here
    }
}

This basic method can be improved upon, e.g. http://www.koonsolo.com/news/dewitters-gameloop/ and http://gafferongames.com/game-physics/fix-your-timestep/.

Alternatively, you could create a timer and set this timer to run your update and rendering every X milliseconds. But, there are some downsides to constructing a gameloop like that.

According to http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html: "Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially. Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes."

According to http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date,%20long%29: "In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate)."

Since you usually don't know ahead of time how long a game loop takes, setting a timer to execute your gameloop every X milliseconds (depending on target frame rate) could lead to a few bunched up frames, which would execute whenever a frame is finished instead of when a frame is scheduled. When that happens... why use a timer in the first place?

Now, don't get me wrong, timer is not a bad class, but it is usually better suited to small tasks which need to be done periodically or at a certain time, e.g. a mail client might want to check for new mail every 5 minutes, or a counter might get decremented every second to display a countdown before the start of a race.

\$\endgroup\$
2
  • \$\begingroup\$ The question was about game loops so the awt/swing information is off-topic. However it looked like that information was relevant because of an irrelevant and confusing line in the question, so I removed that. \$\endgroup\$
    – jhocking
    Apr 14, 2013 at 14:11
  • \$\begingroup\$ I adapted my answer to reflect the changes made to the question. \$\endgroup\$
    – Exilyth
    Apr 14, 2013 at 16:00
7
\$\begingroup\$

I would not put the main loop in a timer. Rather I would make a 'while' loop that processes every frame and then use some sort of timekeeping functionality (it sounds like in Java that would be System.nanoTime) to calculate how much time has passed since the last frame/last iteration of the loop.

Certain languages are exceptions here (eg. JavaScript, ActionScript) because those languages operate within an environment that has an implicit main loop to hook into (eg. the browser, the Flash Player) but that exception doesn't apply to Java.

\$\endgroup\$

You must log in to answer this question.

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