Writing

Timers: Part Two

Timers:
Part One | Part Two


Lets start with a review of Part One.

  • Any increments of 10 ms jitters Java on Windows.
  • High frame rates are not as important as smooth graphics
  • The loopGame delay smoother must never be negative.

With this in mind, I've decided to build a simple but real game called "Subby and the fishes." For the beginning of my development, I was setup on my desktop PC. With my delay smoother set to 21 milliseconds and a hefty graphics card, a Radeon 3800, everything ran smoothly.

Once I moved the code over to my laptop with the Intel video chipset, my delay smoother started hitting negative numbers again. My output was 21, 6, 6, -7, 21, 21, 6. I watched the screen and sure enough the bubbles I had floating up on the splash screen jittered. Bah!

I had to up my delay up to 31 milliseconds. Note I couldn't do 30 because of the Java bug that causes more jitter.

long sleep = loopTime+31-System.currentTimeMillis();
System.out.println(sleep); // check to make sure never negative
try { Thread.sleep(sleep); } catch (Exception e) {}

Ok now I viewed the screen. Still jittering...what the hell.

I checked to make sure my animation was using the smoother. Yes, my move smoother was using the timeLapse variable of the game . Now, when I thought about it, something didn't make sense. Since my game loop was smooth, in other words, never negative, that meant that the time lapse variable I sent to move things should be pretty darn close to constant.

delta = (int) ((timeLapse * speed) / 1000);
System.out.println(delta);

It should be constant but it wasn't. It was all over the place with an output of variance of 6 pixels. Wow, it was terrible. Time to research. Hours later I found David Holmes blog.

http://blogs.sun.com/dholmes/entry/inside_the_hotspot_vm_clocks

Okay it has a ton of information and I'm thankful for it. It just strikes me that if Java was serious about becoming a major gaming platform they would come up with a better than C++ solution for timers. One can only dream right?

So what in the article is useful? I decided to try to force high resolution and recheck my movement delta.

--xx:+ForceTimeHighResolution

My output was perfect. 14, 13, 14, 13, 14. All the movements were within one pixel of each other and looked much smoother.

So for the time being a delay of 31 milliseconds and forced high resolution timer seems to be good enough of my lap top. I really want to test on some even slower machines to make sure my smoother delay is large enough but I'm going to wait until the game is more complete.

NanoTime

I wrote a nano timer as well but had the same poor results. Since the resolution of the the thread.sleep is in milliseconds I think milliseconds are probably the best resolution you can hope for. I also found the manipulation of nano time more than a little annoying. It was very hard to tell how many zeros in the code. 1,000,000,000 is fairly easy to read but 100000000 is not--note the error. Writing 1000*1000*1000 seemed awkward.

I also made a half hearted attempt at using the delay. However, I would have to set up my animation code quite a bit differently to use this. At first brush, it seems like this would make my code simpler but it is not the way I've implemented my animations. Perhaps in the next game I'll try this loop from the outset.

I've tried GageTimer as well as per Kevin Glass's recommendation. However, I found it just as varied as writing my own.



Notes and Links:

Here are some things I'm still trying to organize.


http://stackoverflow.com/questions/351565/system-currenttimemillis-vs-system-nanotime
Need to figure this out.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6435126

0 comments:

Post a Comment

Thanks for the comment.