I'm new here, so I apologize in advance if this is irrelevant or obviously answered in another thread.

I've been working on a 2D gravity simulator, and I've found that when I run the code on my laptop (which is reasonably fast), it goes at the speed that I want it to. However, when I run the code on my PC (which is slow), I find that it goes at about half the speed that I want it to.

The physics for the game is done inside the paint() method of JComponent, which is indirectly called by javax.swing.Timer every 10 milliseconds.

My question is this: Is there any way to animate with Graphics2D so that the animation speed is constant, no matter how fast the computer is? Or, if I'm using the wrong classes for animation, what is a good alternative for what I'm trying to do?

You update your simulation a number of times per second, and draw in the remaining time, if drawing takes too much time you compensate by skipping drawing and updating less.Search on how to write a good game loop.

The util.timer has been shown to be a better choice than the swing.timer. Chapter two of "Killer Game Programming" compares the two. This chapter also has some good discussion on game loops that don't use timers.

The big issue with the swing.timer is that everything it does is queued onto the Event Dispatch Thread. This thread can get kind of backed up if there is too much going on. The utility timer creates new threads.

Another issue is that many Microsoft OS setups will only resolve to about 15 or 16 msecs. Thread.sleep(), scheduling for the timer, and System.currentTimeMillis() all suffer from this. System.nanoTime(), in contrast, uses the JVM's "high resolution time source". In any event, scheduling the events for every 10ms is kind of problematic. Something more on the range of 60fps is more reasonable (16.6 milliseconds) in terms of fitting with the OS's that I know about anyway.

A "newish" class might even be a better choice than the utility timer: [quote from API follows] "ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer."

You can set it to recur at the exact interval rather than at a delta interval. Utility timer has this too: use the method sheduleAtFixedRate() instead of schedule().

I would put the physics in its own method. I would have the timer or game loop call an "update()" for the physics and a "render()" for the draw, as two commands. In this case, the render() might only consist of a repaint() for the JComponent being used for the display.

If I recall correctly there's been some discussion that one should prefer to overwrite paintComponent() instead of paint(). I think there are notes in the API that explain why. It might not matter in your case. I don't know.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org