Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Sleep based timer hack  (Read 7205 times)
0 Members and 1 Guest are viewing this topic.
Offline Jeff

JGO Coder




Got any cats?


« Posted 2002-10-23 22:19:21 »

This one gets asked alot, so I thought I'd post it seperately.

Attributions:  
Contributed to the community by TheLorax.
This version from mbishop's pacman clone.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
// SleepTimer.java
// Here we have "thelorax"'s famous "sleep" timer.  This uses Thread.sleep()
// to get higher-resolution timing under Windows 9x platforms.
public class SleepTimer implements Runnable {

   // Number of elapsed ticks.  A tick is fired every time a sleep occurs.
   private int ticks;

   // The Thread that will be run.
   private Thread timerThread;

   // Our current delay and our desired delay.
   private long msDelay, targetMs;

   // Do we let this Thread correct itself?
   private boolean autoCorrection = true;

   // Is this Thread running?
   private boolean running = false;

   // Difference since last tick.
   private long timeDiff;

   // Desired frames per second.
   private int autoLength;

   // Start time and end time.
   private long startTime, endTime;

   // Of course we want a high priority to do our timing right.
   public SleepTimer() {
      timerThread = new Thread(this);
      timerThread.setPriority(Thread.MAX_PRIORITY);
      timerThread.setDaemon(true);
   }

   public int getTickCount() {
      return ticks;
   }

   // I added this so I could see the number of ticks missed
   // on a per-second basis.
   public void resetTickCount() {
      ticks = 0;
   }

   public void startTimer() {
      running = true;
      timerThread.start();
   }

   public void stopTimer() {
      running = false;
      try {
         timerThread.join();
      }
      catch (Exception e) {}
   }

   // We set auto-correction with a desired frames (ticks) per second.
   public void setAutoCorrection(boolean on, int sampleLength) {
      autoCorrection = on;
      autoLength = sampleLength;
   }

   public void setDelay(int tmsDelay) {
      msDelay = tmsDelay;
      targetMs = msDelay;
   }

   // Sleeps the specified amount, lets other Threads know, then
   // corrects itself if auto-correcting is set.
   public void run() {
      startTime = System.currentTimeMillis();
      try {
         while (running) {
            Thread.sleep(msDelay);
            ticks++;

            synchronized(this) {
               notifyAll();
            }
            if (autoCorrection && (ticks % autoLength == 0)) {
               endTime = System.currentTimeMillis();
               timeDiff = ((endTime - startTime) / autoLength) - targetMs;
               startTime = endTime;
               if (timeDiff > 0) {
                  msDelay--;
               }
               if (timeDiff < 0) {
                  msDelay++;
               }
            }
         }
      }
      catch (Exception e) {
         System.err.println("Exception in Timer Thread.");
         e.printStackTrace();
      }
   }
}

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline GergisKhan

Junior Devvie




&quot;C8 H10 N4 O2&quot;


« Reply #1 - Posted 2002-10-24 14:56:46 »

Thanks Jeff.  I had not wanted to post it until giving TheLorax a chance to do so, but you beat me to the punch. Smiley

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Jeff

JGO Coder




Got any cats?


« Reply #2 - Posted 2002-10-24 17:44:44 »

Yeah, i had to thin kthis one through carefully as I'm very dilligent about author's rights, beign one myself.

Since Lorax has it publically posted  in the archives though, and mbishop had already posted a link to his source, I assumed an implicit permission to repost.  (If I was wrong guys, tell Chris to remove it and hit me with a wet tuna Smiley )

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mbishop78

Senior Newbie





« Reply #3 - Posted 2002-10-26 00:05:53 »

Thanks for digging it out and posting it.  I was a bit leery about doing it myself, but he did post it and I did give him credit in the code... Smiley

Michael Bishop
Offline Captain-Goatse

Junior Devvie




I suck at teh 2D. XBOX IS BIG LOL!111


« Reply #4 - Posted 2002-11-01 08:50:07 »

I have been trying to understand how this timer hack works, but it seems to be that I get randomly error in timerthread where time out value is negative. I have figured out that his has something to do with too small autoCorrection values. The picture thread just freezes.

I've also found out that with this "hack" i see slowdowns after a period of time and it is repetitive.

Can someone please lighten me up on the use of this thing before I implement it into my game. Otherwise it seems to be really great, except for those two little faults on my side.

I'm also kind of confused with this 1.4 fullscreen rendering because of the lack of paint and update methods in away. I guess it just time to get used to it. Does anyone have any article where I could review the basic principles of fullscreen animation? It seems like a lot of the AWT rules are now old and almost useless.
Offline mbishop78

Senior Newbie





« Reply #5 - Posted 2002-11-01 11:57:02 »

This is all the code I used to get it running at "fps" fps.

frameTimer = new SleepTimer();
frameTimer.setDelay(1000 / fps);
frameTimer.setAutoCorrection(true, fps);
frameTimer.startTimer();

I've never had it throw an error before.  Then again, I haven't run it over 60 frames-per-second.

Michael Bishop
Offline Captain-Goatse

Junior Devvie




I suck at teh 2D. XBOX IS BIG LOL!111


« Reply #6 - Posted 2002-11-02 04:28:51 »

Hmm... that makes me wonder what is wrong with my code then...

The animation is smooth for certain amount of time and then it kind of *ticks*. Then it starts over again. I guess I have to start looking through the render loop to see if I can find any nasty code from there.
Offline mbishop78

Senior Newbie





« Reply #7 - Posted 2002-11-06 12:00:49 »

That sounds suspiciously like garbage collection without seeing any code.  Definitely avoid creating objects in your render loop and run it against a profiler.

Michael Bishop
Offline Captain-Goatse

Junior Devvie




I suck at teh 2D. XBOX IS BIG LOL!111


« Reply #8 - Posted 2002-11-06 12:08:59 »

The only object I'm creating is the graphics object. I guess I have to figure out a way to create it outside, but would this really affect? I mean its very simple a aquare moving across the screen and the player rotates around its origin according to mouse and then a moves whatever direction the player decides.

Could the affinetransform be the reason? Now its making the pictures on the roll, but should I make and array of transfromation where the correct transformation gets called each and every time?

The memory usage would be a lot greater, because for smooth animation it would have to be like 70 images or so. 360/5. And then I would have to forget affinetransfroms.

It can't be the graphics 2d object can it? So many other programs create it at the beginning of rendering loop so I highly doubt so.
Offline Captain-Goatse

Junior Devvie




I suck at teh 2D. XBOX IS BIG LOL!111


« Reply #9 - Posted 2002-11-06 15:47:30 »

Hmm I still get the negative timeout error at java native code. Perhaps my garbage collection is wrong and this is really messing up the system. The animation runs really great for the time it twiches. Then after a while the screen freezes dues the negative timeout error.

Edited to say:


It's the mouse rotating the player which causes the problem. Because of the player direction has to be updated all the time, the animation twiches at some point. I will find out why.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jeff

JGO Coder




Got any cats?


« Reply #10 - Posted 2002-11-07 20:01:04 »

Quote
I
I'm also kind of confused with this 1.4 fullscreen rendering because of the lack of paint and update methods in away. I guess it just time to get used to it. Does anyone have any article where I could review the basic principles of fullscreen animation? It seems like a lot of the AWT rules are now old and almost useless.


Yep you are going around the entire AWT paint mechanism when you do Buffer Flipping (and for darn good reasons, you need more control and more efficiency then AWT gives yo uto do cutting edge games.)

Im not sure hwo much there is to explain but Ill do so in the BufferFlipping thread...

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Ssnake

Innocent Bystander




Java games rock!


« Reply #11 - Posted 2002-11-08 18:32:20 »

How is this timer used?
Every time I set this up and call wait() on my main thread,
nothing happens (I get no notifyAll()'s).

Can someone post a sample main() method that sets this
timer up and waits for it to notify it so I can paint?

Thanks  Huh
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #12 - Posted 2002-11-09 20:59:27 »

This could be a stupid idea, but maybe javax.sound.sampled could be misused to mimic a high(-er) resolution timer?
I was thinking about setting up a dataline and fill the buffer with exactly the amount of samples that would last one frame and then wait for the buffer to empty before going to the next frame.

I haven't got around to try it yet, but I think it could work in theory, although there could be some performance loss.

Just a thought...

Smiley Erik

8: Undefined index: online
File: /home/jgo/public_html/Themes/default/Display.template.php (main sub template - eval?)
Line: 161