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  
  the ticks inside a timer loop  (Read 3966 times)
0 Members and 1 Guest are viewing this topic.
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Posted 2003-07-29 22:11:47 »

I have seen bits of code of different timming loops and they all have the tick variables. I was wondering whats the theory behind these ticks? I wish to do a few things like update ai, frame independed movement, and fps display and know all these things require tracking the ticks inside a timming loop. But I am a bit confused how are variables like curretTick lastTick are used and what do they mean.

Kommi
Offline GergisKhan

Junior Devvie




"C8 H10 N4 O2"


« Reply #1 - Posted 2003-07-30 00:19:10 »

Kommi,

I'm not entirely sure which code you've seen, but I don't think it matters.

There's a timer that runs during the game loop.  This timer may or may not be at the rate you want, or (as in the case of the Windows high performance timer which is used by GAGE and my own library) runs MUCH faster than you need.  The Windows runs in microseconds, whereas most platforms will give you a one millisecond resolution on System.getCurrentTimeMillis().

Because the timer may not be completely divisible with your loop, you might encounter "drift" where you lose a few milliseconds here or there.  So most loops have what's called a "delta" which is the time between the current "tick" of the clock, and the previous one, so that you can lengthen or shorten the next "tick."

So what are these ticks?  Well, I'm assuming you're not attempting 1000fps, which would mean 1 millisecond per frame.  Rather, let's say like I do that you have eight frames of animation and you want to display them in one second.  This gives you 125 milliseconds for each update, and therefore you have 8 "ticks" per second.

Naturally the timer doesn't care what my game ticks are; it runs at its speed.  So in truth I'm clocking some 140000 ticks between frames, and if I adjust for drift I have to know how much longer or shorter to sleep for to keep to that 140000 ticks per frame (the reason it isn't 125000 ticks is that the windows timer is actually running at slightly higher than 1 million ticks per second.  On a Mac, it's exactly 1 tick per millisecond, so I would have 125 ticks between frames, and I would adjust accordingly).

I know this might sound a bit convoluted, so feel free to ask for clarification.

gK

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

Junior Devvie




All opinions will be lined up and shot!


« Reply #2 - Posted 2003-07-30 10:53:58 »

I have a native timer implementation with a granularity of 25.6574... microseconds. This is very accurate but since its not my code I am not sure how much access I have to the timer. I will post my code later in the day and maybe someone will help me write a tick implementation. Hey  GergisKhan,  I was wondering whats the granularity of the GAGE implementation?


Kommi
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #3 - Posted 2003-07-30 12:31:45 »

Quote
I was wondering whats the granularity of the GAGE implementation?


It varies from system to system, but the GAGE timer guarantees at least 1 ms resolution on all systems. On Windows, it does far, far better. Probably the same resolution as your timer considering that it uses the standard Windows Hi-Res timer.

Java Game Console Project
Last Journal Entry: 12/17/04
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #4 - Posted 2003-07-30 14:42:45 »

OK so let me see if I got it:
If I have a timer with aprox 1000 ticks per second

then if I want 60 fps I have to redraw every 1000/60 = 16.6 ticks

If I want an 8 fps char animation I have to update it every 1000/8 = 125 ticks

and if my char moves 1 pix at a time and I want him to move 20 pix/sec then I have to update his location every 50 ticks. I would also do collision detection and check for keyboard at this interval.

Did I get the idea right? Or am I missing something?
I have decided to switch over to the GAGE timer implementation.

Question 2
Can someone please remind what to do with the file I got from http://java.dnsalias.com/ for the hires timer.
I cant remeber wether I have to unzip it or just set a class path to it or what. Can someone please describe the setup and any import statements that I will have to put in my code. Thanx

Kommi
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #5 - Posted 2003-07-30 20:07:14 »

You've got it. Don't worry too much about the .6 ticks tho. They usually get rounded out of the equation thanks to VSyncs.

AS for how to use the timer, there are two files to worry about. "timer.dll" must always be in the directory you launch your app from. If you see an exception on startup and your app seems to run jerky, you probably don't have it in the right place. Timer.dll can either be referenced in the classpath (usually using the path in an executable JAR file) or it can be extracted and put in your own JAR file.

Java Game Console Project
Last Journal Entry: 12/17/04
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #6 - Posted 2003-07-30 21:00:09 »

Thanx for the reply but one more newbie question. If I have your file then where do I unzip it to and how do I set the classpath for it? Also I take it that I just do AdvancedTimer timer = new AdvancedTimer(); in my code without importing anything?

Kommi
Offline Frumple

Junior Newbie





« Reply #7 - Posted 2003-07-30 22:43:29 »

You need to import com.java.dnsalias.timer.*; whenever you instantiate a timer i think. I decided not to fiddle with the .dll file yet, instead I took the com directory from the bin folder in the zip archive and dumped it into the same main directory of my project. Then I would just refer to the AdvancedTimer class just like any of my own classes in my game.
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #8 - Posted 2003-07-31 17:29:36 »

I take it that the ticks per second depend on the cpu speed of the machine. I am getting 3,500,000 ticks per second on my Athlon XP1800 WIN2K using the GAGE timer.
Question: If I want to setup the delta ticks mechanism I would call getClockTicks() twice, once before
sleepUntil(), once after, and then take the difference right?

Kommi
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #9 - Posted 2003-07-31 18:33:19 »

Delta of what? For the equations you have above (1000/60, etc.) you simply need to replace 1000 with timer.getTicksPerSecond(). Thus:

long ticksPerFrame =  timer.getTicksPerSecond()/60;

Java Game Console Project
Last Journal Entry: 12/17/04
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #10 - Posted 2003-07-31 18:45:12 »

Yeah its fine if I want the frame rate to be 60 fps then

sleepTime = timer.getTicksPerSecond()/60;
.
.
dostuff();

timer.sleepUntil(ticks+sleepTime);
   ticks += sleepTime;

But what if I want an animation to update its frame once every timer.getTicksPerSecond()/8  which is 8fps
then how would I implement that?

Kommi
Offline GergisKhan

Junior Devvie




"C8 H10 N4 O2"


« Reply #11 - Posted 2003-07-31 23:48:48 »

Kommi,

I believe there are in fact two frame rates involved here.  If you are using BufferStrategy, I don't think you need worry about one of them.

There are in fact two different rates going here.  In fullscreen mode using BufferStrategy, the screen will refresh itself at whatever the monitor refresh rate is.  If you are set to 60Hz, then the screen will display 60 frames per second.

This is different than your own refreshes, which, if I read you correctly, indicates you have eight frames of animation to display.

Simply ignore what the BufferStrategy is doing.  Refresh at ticksPerSecond()/8 and the rest of the frames will simply use whatever is in the buffer at that time.  Remember, you're not updating the screen itself, you're updating the buffer.  The screen refresh uses whatver buffer contents are available.

gK

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

Junior Devvie




"C8 H10 N4 O2"


« Reply #12 - Posted 2003-07-31 23:51:59 »

An additional thought: you may wish to time your animation loop.  To do this, I modified the AdvancedTimer so that getTime() is now public.

int start = timer.getTime();

render();

updateSprites();

int timeOfFrame = timer.getTime() - start;

timer.sleep( ( timer.getTicksPerSecond() / 8 ) - timeOfFrame );


This fragment ensures that I'm sleeping for the exact amount of an 8 frame refresh, and stablizes the loop somewhat.  You need to assure, however, that you can complete all operations within 125 milliseconds, or else this idea doesn't work.

gK

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

Senior Newbie




Welcome to my world!


« Reply #13 - Posted 2003-08-01 04:42:02 »

I'm checking out the gage timer for our game and I get a unsatisfied link error: getResolution

I'm calling System.loadLibrary("timer"); before hand and I get no error with this call so it is loading the timer.dll-I know I don't have to do this because its done inside the WindowsTimer class, its there just for testing.

I'm also compiling the AdvanceTimer, NativeTimer and WindowsTimer java files with my own files so I don't have to import anything. I changed the Package to my package name as well, everything compiles fine, just getting the runtime error.

Online kevglass

« JGO Spiffy Duke »


Medals: 212
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #14 - Posted 2003-08-01 04:59:55 »

Changing the package names will break the JNI interface. The naming of the C functions created is based on the package name of the class.

Kev

Offline vydias

Senior Newbie




Welcome to my world!


« Reply #15 - Posted 2003-08-01 15:28:06 »

Ok good point, but still having problems with the same error, when I just import that timer.jar file.

I can compile and I don't throw an error when it loads in the dll, I have access to all the timer classes but still when running I get the unsatisfied link error: getResolution when asking for the GAME_TIMER.getTicksPerSecond()/60;

Any suggestions?

Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #16 - Posted 2003-08-01 16:32:49 »

I dont think I made my question clear in the last post. So here is the situation. Lets say I am updating 3 diffrent things:
1. The whats drawn to the screen
2. The char location
3. AI

Now lets say I have a 1000 ticks per second (in theory of course).
1. If I want 60ps then I have to update the draw() once every 1000/60 = 16 ticks.
2. If I want the char location and other things pertaining to it at 20 times a second then that gets updated every 50 ticks. The character also has an 8fps animation that gets updated once every 125 ticks.
3. Now lets say the AI gets updated once every 300 ticks.

My problem is that I am not sure as to how to manage these updates. According to the above, one second of game time gets the following calls:
0,1,2,3,4,...16 draw(),17,18,...32draw()...48 draw(),49,50 updateChar(),...

So I have to setup a mechanism that calls my methods at certain time intervals. to make sure that the timer sleeps once every (1000/60) ticks and the game loop calls updateChar() once every(1000/20) ticks, and calls AI() once every (1000/3) ticks. My prob is that I am not sure how to implement this. At first I thought I would need a delta ticks to keep track of how many ticks passed and then call certain methods at a certain value of delta ticks. But now Im not sure.
This problem is similar to trying to implement frame independent movement. That implementatiomn uses delta ticks so I am guessing that I need it here as well.
I hope I my post is not confusing enough Smiley

Kommi
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #17 - Posted 2003-08-02 00:22:22 »

Quote
An additional thought: you may wish to time your animation loop.  To do this, I modified the AdvancedTimer so that getTime() is now public.


Why in the world did you do that? Is there something wrong with clock ticks?

Quote
Ok good point, but still having problems with the same error, when I just import that timer.jar file.


1. Do *not* call System.loadLibrary. The timer calls it on its own. A second call will merely result in an exception.
2. Make sure that timer.dll is either in the same directory as you are running the code from, or that it's in the system PATH (e.g. c:\winnt\system32)

Quote

My problem is that I am not sure as to how to manage these updates. According to the above, one second of game time gets the following calls:
0,1,2,3,4,...16 draw(),17,18,...32draw()...48 draw(),49,50 updateChar(),...


Off the top of my head algo, assuming 1000/sec:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
long nextDraw = timer.getClockTicks()+16;
long nextChar = timer.getClockTicks()+50;
long nextAI = timer.getClockTicks()+300;

while(true)
{
  if(nextDraw < timer.getClockTicks())
  {
    drawStuff();
    nextDraw = nextDraw+16;
  }

  if(nextChar < timer.getClockTicks())
  {
    doCharacterStuff();
    nextChar = nextChar+50;
  }

  if(nextAI < timer.getClockTicks())
  {
    doAIStuff();
    nextAI = nextAI+300;
  }
}


Ok, gotta jet. Busy, busy, busy. That's what this most recent DD release is... Smiley

EDIT: Fixed a goof-up in the if statements of my example code.

Java Game Console Project
Last Journal Entry: 12/17/04
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #18 - Posted 2003-08-02 14:32:56 »

Wow thats pretty cool. I have tried your code jbanes, and naturally it works Smiley Its interesting how there is no timer.sleep involved. Although the effect is the same as with a sleep. I take it that calling methods at certain amounts of ticks without a sleep method is a much better way of doing the game loop, as it allows for more control. I was wondering if this is how it is usually done?

Kommi
Online kevglass

« JGO Spiffy Duke »


Medals: 212
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #19 - Posted 2003-08-02 15:22:52 »

This would cause problems if you were using more than one thread tho, might slow down AWT thread for instance? Is that right?

Kev

Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #20 - Posted 2003-08-02 16:22:43 »

I am only using one thread and the cpu usage is pretty low when running. I dont know how it will be when I have a much more complex engine. Stability might become an issue. I am not sure wether running a loop that checks every tick is effifcient and safe.  

Kommi
Offline GergisKhan

Junior Devvie




&quot;C8 H10 N4 O2&quot;


« Reply #21 - Posted 2003-08-02 18:31:36 »

Quote


Why in the world did you do that? Is there something wrong with clock ticks?



I had a really good reason for doing it.  Unfortunately, I can't remember it so it must not be that good of a reason!  Cheesy

Seriously, I think I had needed to find out exactly what the time is and for whatever reason getClockTicks() was not acting as either I expected, or else there's something really convoluted and wrong about my code.  At this point since the loop was changed I think I no longer needed.

What about the wisdom of not using sleep at all in this case... is that cool?  I see a potential flaw if your draw code takes longer than the ai's next tick... which means I guess you skip it if it's taken too long to do any one operation.

gK

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

Junior Devvie




All opinions will be lined up and shot!


« Reply #22 - Posted 2003-08-02 20:38:45 »

Yeah I am concerned about that. I dont think that not hjaving sleep and building in all these safety checks is not the smoothest way. Hey GergisKhan what does your loop look like? How do you solve the problem of having different updates at different specified intervals during a second of time?  

Kommi
Offline GergisKhan

Junior Devvie




&quot;C8 H10 N4 O2&quot;


« Reply #23 - Posted 2003-08-02 22:10:52 »

Actually, I didn't really solve it.  I just update everything clientside whenever the frame is supposed to refresh.  That's because very little should really be going on clientside that requires more than a 1/8th of a second refresh.

All of my AI work is server-side.  Had I been doing this as a standalone (which is my NEXT project for demo purposes) I would still resort to a single call.  The reason for this is that I feel more comfortable knowing that I'll get in one redraw and one update, and a few ticks left over to sleep in.

Sample, not production code:

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  
      public void run()
      {
            long startTime;
            long endTime;

            boolean contentsLost = false;
            try
            {
                  while ( doRender )
                  {
                        if ( !pauseRender )
                        {
                              startTime = timer.getTime();

                              if ( doRender( null ) )
                              {
                                    bufferStrategy.show();
                              }
          updateSprites();
                              endTime = timer.getTime();

                              timer.sleep( renderLoopSpeed - ( endTime - startTime) );
                        }
                  }
            }
            catch ( Exception x )
            {
            }
      }

gK

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

Junior Devvie




All opinions will be lined up and shot!


« Reply #24 - Posted 2003-08-03 02:04:00 »

I had the same implementation where I would do all the updates during the interval where I refreshed my frame. The problem is that after a while If I have my character running through a bar and there are 20 npc's in the bar then there are a lot of things going on that need to be updated. I have a bouning box collision setup, but since my world is iso I also have collision that relys on the geometry of the tiles. So I have a bar drawn, then all the objects like tables and such, then the keyboard and mouse events are taken care of, then collision detection happens between all the sprites and the environment, then movement. It gets really complex as I go along and I dont think updating everything 60 times a second is a viable option (or a good one). Especially since alot of the things like movement and character animations do not need to be updated every frame.  

I was wonedering how else I should handle this situation. What kind of loops do some of you guys use that work ell for a complex game?

Kommi
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #25 - Posted 2003-08-03 02:29:33 »

I highly suggest you look at the way GAGE handles collisions. There's no need to test every object against every object, just test possible types of collisions. 60 FPS should be no problem then.

As for your loop, as long as you have your AI and Character stuff as multiples of your time between frames (or at least close), you can do this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
long nextDraw = timer.getClockTicks()+16;
long nextChar = timer.getClockTicks()+50;
long nextAI = timer.getClockTicks()+300;
 
while(true)
{
  drawStuff();
  nextDraw = nextDraw+16;
 
  if(nextChar < timer.getClockTicks())
  {
    doCharacterStuff();
    nextChar = nextChar+50;
  }
 
  if(nextAI < timer.getClockTicks())
  {
    doAIStuff();
    nextAI = nextAI+300;
  }

  timer.sleepUntil(nextDraw);
}

Java Game Console Project
Last Journal Entry: 12/17/04
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #26 - Posted 2003-08-03 13:14:25 »

I did my own collision detection so I can learn how to do it properly. It was the first time I wrote fast effecient collision detection between objects other than simple rectangles. I am actually now looking at the GAGE code so as to see what areas I can improve.
The loop you have is the one that I am currently using and experimenting with. I was wondering what do you mean by my other updates being multiples of my time between frames. Edit: Nevermind I got it.
I will continue to use the loop you suggest but am still intrested in other people's implementations on this matter. I guess I am still asking for solutions to doing different updates during different time intervals within a second of game time.


Hey jbanes, I was wondering how does your collision detection work, theoretically? In the Javadocs it says "Currently, this code uses brute force comparing to decide whether a collision has occurred". In my collision detection I have  bounding box check that when violated I then do calculations on the geometry. But I still have to do bounding box between a sprite and all the other sprites that it can collide with every update.

Kommi
Offline vydias

Senior Newbie




Welcome to my world!


« Reply #27 - Posted 2003-08-03 23:31:59 »

Quote

1. Do *not* call System.loadLibrary. The timer calls it on its own. A second call will merely result in an exception.
2. Make sure that timer.dll is either in the same directory as you are running the code from, or that it's in the system PATH (e.g. c:\winnt\system32)


If you look above I only put it in their for a quick test. after that didn't fix it I removed it and looked at the java classes that came with timer and saw that it was loaded in nativeTimer. But it didn't throw any new errors including it in there a 2nd time.

Also I've got the timer.dll is in my program directory and I still get the error- I've pretty much put the timer.dll everywhere possible after this didn't work-still nothing. Only thing I can think of is maybe the jar file is older then the .dll and something was changed recently in the timer .dll? I didn't get the jar file with the latest download of the timer.zip but found it somewhere else. If this isn't the problem I'm seeing no other reason why it shouldn't be working. jar file is being imported and dll is being loaded...
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #28 - Posted 2003-08-04 09:24:46 »

Quick question, whats the proper algorithm for displaying the framerate? Shoud I just have a counter inside my redraw() and have that printed to the screen once every second? Or is there a more accurate way of getting the actual fps?

Kommi
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #29 - Posted 2003-08-07 15:17:09 »

Vydias, can you post your code here? Also, do a search on your system to make sure that you have no other files called "timer.dll".

Kommi:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
long frametime = 0;
long fps;

while(true)
{
  frametime = timer.getClockTicks();
    
   ...
  
   fps = timer.getTickPerSecond()/(timer.getClockTicks()-frametime);
}

Java Game Console Project
Last Journal Entry: 12/17/04
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (36 views)
2014-12-15 09:26:44

Mr.CodeIt (29 views)
2014-12-14 19:50:38

BurntPizza (61 views)
2014-12-09 22:41:13

BurntPizza (98 views)
2014-12-08 04:46:31

JscottyBieshaar (58 views)
2014-12-05 12:39:02

SHC (74 views)
2014-12-03 16:27:13

CopyableCougar4 (76 views)
2014-11-29 21:32:03

toopeicgaming1999 (137 views)
2014-11-26 15:22:04

toopeicgaming1999 (127 views)
2014-11-26 15:20:36

toopeicgaming1999 (37 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!