Timing movements in seconds?
Blitz3D Forums/Blitz3D Beginners Area/Timing movements in seconds?
| ||
Hi, I need a timing system that uses seconds and not animation frames to govern the movements of objects in a scene. The CreateTimer(), WaitTimer() approach is no good in this instance because it uses frame frequency. Can someone who knows basic mathematics show me why the following code doesn't work. ; Basic timed movement ; ------------------ ; ; doesn't work. Why? ; ; need to move the object over a set distance (6.5) in a set time (3 secs) ; time needs to be in seconds NOT frames ; Set 3D graphics mode Graphics3D 640,480,16,0 SetBuffer BackBuffer() camera=CreateCamera() light=CreateLight() cone=CreateCone( 32 ) PositionEntity cone,-3,0,5 distance# = 6.5 ;blitz units time# = 3.0 ;secs speed# = Float(distance / time) currentpos# = 0.0 While Not KeyDown( 1 ) If (currentpos < distance) MoveEntity(cone, speed, 0, 0) currentpos = currentpos + speed EndIf UpdateWorld() RenderWorld() Flip Wend ClearWorld() End Thanks, Rogue Vector |
| ||
Greetings Puppies, Check out the Millisecs() command and base your stuff on that? Peace, Jes |
| ||
I know about the millisecs() command. But there are still problems with the timing. Objects move in a jerky way and inaccuracy creeps in. Observe, ; Basic timed movement ; ------------------ ; ; need to move the object over a set distance (6.5) in a set time (3 secs) ; time needs to be in seconds NOT frames ; ; PROBLEM - NOT ACCURATE and the object needs to move more smoothly and eliminated the jerkyness ;----------------------------------------------------------------------------- ; Set 3D graphics mode Graphics3D 640,480,16,0 SetBuffer BackBuffer() camera=CreateCamera() light=CreateLight() cone=CreateCone( 32 ) PositionEntity cone,-3,0,5 distance# = 6.5 ;blitz units time# = 3.0 ;seconds speed# = Float(distance / time);result is blitz units per second currentpos# = 0.0 clock = 0 timer = 0 While Not KeyDown( 1 ) clock = MilliSecs() If (timer + Float(1000 / 4) < clock) ;clock every 250 milliseconds (1/4 second) If (currentpos < distance) MoveEntity(cone, speed / 4 , 0, 0) currentpos = currentpos + speed / 4 EndIf timer = clock EndIf UpdateWorld() RenderWorld() Text 2, 5, CurrentTime$() Flip Wend ClearWorld() End Rogue Vector |
| ||
Instead of moving the object every 250 milliseconds, you need to move the object based on the number of miilisecs since the last update. Like this:; Set 3D graphics mode Graphics3D 640,480,16,0 SetBuffer BackBuffer() camera=CreateCamera() light=CreateLight() cone=CreateCone( 32 ) PositionEntity cone,-3,0,5 distance# = 6.5 ;blitz units time# = 3.0 ;seconds speed# = Float(distance / time);result is blitz units per second speedpertick# = Float(speed#/1000);result is blitz units per tick currentpos# = 0.0 clock = MilliSecs() starttime = clock While Not KeyDown( 1 ) ticks = MilliSecs() - clock clock = MilliSecs() If (currentpos < distance) distancemovedthisupdate# = speedpertick# * ticks MoveEntity(cone, distancemovedthisupdate, 0, 0) currentpos = currentpos + distancemovedthisupdate Else Text 2, 60, "Took " + (MilliSecs() - StartTime) + " milliseconds" Flip WaitKey End End If UpdateWorld() RenderWorld() Text 2, 5, CurrentTime$() Text 2, 30, currentpos Flip Wend ClearWorld() End That way it always moves at the same speed regardless of the framerate. Edit: sorry, I didn't notice the significance of currentpos at first :-) Edit: also, it'll never be *exactly* 6.5 units, or 3000 milliseconds because of the vagaries of PC performance, (my PC was doing a frame about every 17 milliseconds, which just doesn't divide cleanly into 3000) but it should be accurate enough for most purposes. |
| ||
Thanks! Rogue Vector, |
| ||
No problem. |
| ||
Rogue Vector, take a look at my Frame Limiting Code (the link is on the left) to see how to apply it to your games. http://home.cmit.net/rwolbeck/programmingtutorial |