All the same speed?

Blitz3D Forums/Blitz3D Beginners Area/All the same speed?

JBR(Posted 2003) [#1]
Hi, my question is about making a 'game' run at the same speed on many different computers.

I'm using a computer with a screen refresh rate of 60Hz. Currently I get everything done within the frame, so that the game works smoothly.

I only have a P3 600Mhz with an LCD at 60Hz. I've heard quoted that monitor refresh can be a lot faster than 60Hz which would make my game probably run faster than what it should.

Basically I'd like to know how to make the game work at the same speed on any computer and have smooth animation.

I've had a look at some games sources and they do something like the following.

GameTimer = CreateTimer(30)
NoOfUpdates = WaitTimer(GameTimer)
For Count=1 To NoOfUpdates
UpdateGame()
Next
RenderGame()

Can someone explain this a little bit? Or point me in the right direction?

Thanks
Marg


jhocking(Posted 2003) [#2]
It depends if you're talking about a 2D or 3D game. There are different approaches to each.

That said, the WaitTimer approach is pretty simple (if far from ideal.) However that code complicates things. In that code the game is updated more often than it is rendered, kind of a silly approach for most games (although the additional updates between rendered frames makes a difference for stuff like calculating physics.) To just have it update and render 30 times/second it would be:

GameTimer=CreatTimer(30)

While Not KeyHit(1)
WaitTimer(GameTimer)
UpdateGame()
RenderGame()
Wend


keyboard(Posted 2003) [#3]
heres a link to a timing example in the code archives:

game timing

The idea behind this code is: Your program measures the gap in Milliseconds between two consecutive time readings. On fast computers this will be a smaller gap, a bigger gap on slow computers. Then the movement of a sprite is calculated by multiplying by that *gap* mentioned above. As a fast machine updates the screen more often, and a slow machine updates a bigger *gap* - the sprite movement is the same on both machines.

hope my explanation makes sense...


Stoop Solo(Posted 2003) [#4]
Hi Marg,

I did it this way with the game I'm working on in BlitzPlus. It's quick 'n' crude, but works out pretty well on the machies I've tried it on so far.

------------------------------------------------------------
gamespeed=9 ;Number of milliseconds each update should take

.gameloop
starttime=millisecs()

cls
---blah blah all the rendering to be done
flip false

---blah blah all the collision checking to be done

---blah blah blah the UDP network stuff

---blah blah read mouse/joystick/keyboard, update movement variables

timeleft=gamespeed-(millisecs()-starttime)
if timeleft>0 delay timeleft
goto gameloop
--------------------------------------------------


Provided the loop is done within the number of millisecs I specify in the gamespeed variable (which for my actual application, it was easily. Damn, B+ is fast!), the game will always update every 9 milliseconds (or whatever gamespeed is set to).

-It takes a reading of the system timer at the start of the loop (starttime)

-runs through all the loop gubbins (rendering, collision, movement etc)

-and at the end works out the remaining time needed to delay (timeleft) by subtracting the time it took to do the loop (millisecs()-starttime) and subtracting it from the time you want the loop to take in total (gamespeed-(millisecs()-starttime)).

-the loop will then delay for the remaining milliseconds (timeleft) (it needs to check that it's greater than zero, as in the event that it does ever go below 1, it will delay forever).

Also, the loop uses Flip False. Flip on it's own will always delay the loop until the next vertical retrace, so the refresh rate of the monitor will impact the game speed (producing the problem you cited), whereas Flip False will just flip the buffer immediately, thus becoming monitor refresh independent.

Good luck! :D


WolRon(Posted 2003) [#5]
if timeleft>0 delay timeleft

I'm not sure that DELAY is the best command to use (depending on the situation of course). Most of the time you are going to want to let the CPU do other tasks while waiting but I don't think that the DELAY command allows this. A better setup would be to use a timer and WaitTimer command.