1

To make things clear, I'm looking for the best possible alternative to implement a 'game loop' in Java (using Swing).

Currently, I'm using the following setup with paintComponent() overridden in the JPanel class for drawing stuff like so:

public void run() {
    while (running) {
        panel.update();
        panel.repaint();
        try {
            sleep(SLEEP_TIME);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

This setup seems to work neatly, but moving shapes and images seems to stutter for a pixel or two at times. In other words, the movement isn't as smooth as I'd like it to be.

I'm wondering if there's a way to do the game loop more efficiently, i.e. to avoid stuttering in the movement?

6
  • Make the cycle rate fixed. Commented Apr 15, 2015 at 17:57
  • And how do I do that? Commented Apr 15, 2015 at 17:59
  • What is the value of SLEEP_TIME? Swing can normally achieve very high frame rates. The stuttering is likely due to some way your program has been written and the small sample you've provided is not enough to determine the problem. See stackoverflow.com/help/mcve Commented Apr 15, 2015 at 18:02
  • The value of SLEEP_TIME is 16. Commented Apr 15, 2015 at 18:07
  • When you paint your graphics, does it use some sort of concurrency lock so that the painting cannot occur when you are updating your shapes? Otherwise they could easily stutter if you paint some shapes whose new looks are only half updated. Commented Apr 15, 2015 at 20:49

1 Answer 1

1

An easy way to make the cycle rate fixed, is using ScheduledExecutorService.

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
    panel.update();
    panel.repaint();
}, 0, 16, TimeUnit.MILLISECONDS);

Another way is doing it by yourself by calculating the time to sleep based on the time used for the process.

public void run() {
    long time = System.currentTimeMillis();
    while (running) {
        panel.update();
        panel.repaint();
        long sleep = 16 - (System.currentTimeMillis() - time);
        time += 16;
        try {
            sleep(sleep);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly the method recommended in Game Programming Patterns: Game Loop. gameprogrammingpatterns.com/game-loop.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.