I posted this the other day in the Real Game Tools Furum regarding this subject:
I have seen a lot of DB games and demos that use SYNC RATE as a way to limit their games speed. I used to use that method myself.
There are problems with doing it that way that I am sure most of you are aware of:
- The games run slower on slower machines
- People that have good computers are limited to the max refresh rate that you have set.
-It does not work correctly on all machines. I've had games run at 80fps with the sync rate set to 0. If I set the sync rate to 60 the game will run at something like 50fps instead of the 60 that I set. It only happens on some machines though.
Bottom line is this, people with different computer specs will have different experiences with your games.
I decided on my latest project, Out-Punch ("Mike Tyson's Punch Out" clone), to do the entire game based on the timer to eliminate the Sync Rate FPS problems. While converting to this method, I ran into some problems. The following is a description of how to implement this TIMER method and work around some of the difficult problems that you might face.
I at one time was working on a driving physics engine trying to use this method of refresh. One thing that kept giving me troubles was that while DB said it was running at a consistant frame rate, it was actually jumping around quite a bit. As I am sure you know, when using the timer refresh method instead of the sync rate method, any distance that an object moves has to be multiplied by the time interval. In the sync rate method, if you wanted your object to move, you would tell it to move so many units per loop. In the timer method, you have to figure out how far you want it to move in a certain time frame. For example if I wanted my Object to move 20 units in 1 second, I would have to do something like this:
Time# = TIMER()
DO : `Main Game Loop
elapsedTime# = TIMER() - Time# : `measure the amount of time that has elapsed since the previous loop
Time# = TIMER()
MoveDist# = 20*(elapsedTime#/1000) : `move 20 units per second
MOVE OBJECT 1,MoveDist#
SYNC
LOOP
For the most part, that works fine, and it is what most people use. I however was having problems with it because the elapsed time jumped around alot. In the driving physics code that I was working on that caused a lot of problems because if for some reason the previous refresh took extra long the car would go extra far to match making the game look very jumpy. To remedy this problem I decided to keep a running average of refresh times to use as my multiplier instead of just using the previous refresh time. I don't know if that is a standard practise for anyone else, because I have never seen it before, but it is working really well for me. Here is what I do:
IntLoops = 0 : ` A count of the loops that have occured
Integrator = 10 : `The number of "elapsed times" to keep a running average of
DIM ElTime#(Integrator) : `Array to store the elapsed times
Time# = TIMER()
DO : `Main Game Loop
GOSUB Time
MoveDist# = 20*(Ntime#/1000) : `move 20 units per second
MOVE OBJECT 1,MoveDist#
SYNC
LOOP
`----------------------------------------------------------------------------------------
Time:
`----------------------------------------------------------------------------------------
IF IntLoops <= Integrator THEN IntLoops = IntLoops + 1
FOR a = (Integrator - 1) TO 0 STEP -1
ElTime#(a+1) = ElTime#(a)
NEXT a
ElTime#(0) = TIMER() - Time#
Time# = TIMER()
NTime# = 0
FOR a = 0 TO Integrator
NTime# = NTime# + ElTime#(a)
NEXT a
NTime# = NTime# / IntLoops
IF NTime# = 0 THEN NTime# = 1
RETURN
This method is working very well for me. If you want to try it out, feel free. Using the timer method is definately the professional way to do things and will make a difference. It is a little more work, but it is definately worth the trouble.
If anyone is interested I also have my animation's speed working off of the timer method.
WOLF
HOOOWWWWLLLLL!!!!!!