[java] Keeping constant framerate

Started by
12 comments, last by Tolwyn 23 years, 8 months ago
I think I read somewhere that Timer objects don''t run in a seperate thread, that they were intended for Swing objects which need to be updated but aren''t syncronized. Can someone verify if this is true?

The way my games work is that I grab the current system time at the beginning of the thread, do the hard parts, then grab the time again. Figure out how long it took, and sleep whatever time is left. When I just used a static Thread.sleep(40), the game sped up and slowed down depending on how much work was going on. Sure there are still some bumps in the framerate here and there, but for the most part, it works fine. It is really only obvious when doing scrolling. And I''m doing 2D games so tying the animation to the framerate isn''t a problem. It is almost required.
Advertisement
quote:Original post by Squidi

I think I read somewhere that Timer objects don''t run in a seperate thread, that they were intended for Swing objects which need to be updated but aren''t syncronized. Can someone verify if this is true?



javax.swing.Timer uses a runnable inner class, DoPostEvent, and a singleton instance of TimerQueue, which has its own thread, so Timer objects "run" in *a* seperate thread. To be specific, one DoPostEvent instance runs in the TimerQueue thread for each started instance of Timer.

When you say "intended for Swing objects which need to be updated but aren''t syncronized", what exactly do you mean? I can verify that Timers are useful for changing the state of visual components without involving their painting methods, but that may not be what you were asking. The words "update" and "synchronized" can be a bit ambiguous in this discussion.

ManaSink
quote:Original post by ManaSink
I would also assume that the 50msec updates Icculus and javanerd saw were under Win95/98 VMs.

javanerd, are you saying you encountered a 120% longer execution time using multiple threads vs. a single thread on a single CPU machine? I''m curious if this was due to lock synchronization or thread context switches. I''d be interested in discussing your threading strategy with you some time.


The 50msec updates occured under WinNT 4.0 with JDK 1.2 and Microsoft Java SDK 3.0. Actually the update rate fluctuated a bit around 30-50msec, but mostly staying in the 50msec range.

The 120% increase in execution times (showing up as less frames per second outputted) were propably caused by context switching. As I did have a very light synchronization strategy. The application I was mentioning is an Asteroid emulator that runs the original Asteroid game within a virtual arcade HW. I made use of the fact that the original game had a separate processor for the graphics drawing and thus had to have implemented some kind of synchronization. So I just synchronized the access to the one flag that then triggers the execution of paint process.

I''d be happy to discuss this thing over with you if you like.
-Pasi Keranen
ManaSink:

An example. I was just working on a game test that created a thread for the game logic. It called repaint() to draw the offscreen buffer on the screen, but this was handled by the default thread the applet starts up in. Because there was no synchronization attempts on my part, the applet thread would just paint the buffer whenever it felt like, no matter what state the buffer was in. This led to a lot of flickering and nastiness. I could minimize the time it took to draw stuff to the screen, as well as either skip bad frames or wait on them (both came up with bad results).

Next, I tried using a Timer instead of a seperate Thread object. After repaint is called, the same default applet thread handles the painting...thus no flickering (though the framerate did stutter every dozen frames or so - don''t think that can be helped).

The difference is that Threads work by operating everything from their run() function. A Timer passes an ActionEvent to the applet, and lets the default applet event thread handle it. So a Thread allows you to run stuff at the same time, whereas a Timer will just send action events at a regular interval. Pretty smart thinking.

It is written in "Java Foundation Class in a Nutshell":

"These operations can also be performed with threads, of course, but since Swing is not designed for thread safety, it is usually more convenient to use a Timer."

Anyway, I was a little confused, but I was on the right track. Now I know...and knowing is half the battle.

This topic is closed to new replies.

Advertisement