In programming, there many ways to accomplish the same thing. This is one set of functions that I like to use for managing frame-rate based movement. It does not manage the frame-rate itself, which is another method often used to manage movement.
This set of functions is also probably over-complex for most small projects in that it allows for multiple simulated frame-rates at the same time. For example, it can support a player running at 60 FPS and slow bullets down to a crawl at 5 FPS for a bullet-time type simulation. It also uses the high resolution performance timer (PERFTIMER) for increased accuracy.
Like the code snippet you posted, this also includes a catch for the initial 0 frame as well as some other defensive code.
`============================================================================================================================
`=TIMER BASED MOVEMENT FUNCTIONS=============================================================================================
`============================================================================================================================
`When calling the TimeFactor() function, pass the target virtual frame rate (FrameRate)
`to achieve (i.e. 60 for 60 FPS, or 30 for 30 FPS). A value of 0 defaults to 60 FPS.
`The return value is a percentage; multiply movement, turning, or other timer-based
`factor by the TimeFactor() return value.
`Example: Move Object ObjectID, 1.0 * TimeFactor(60)
`will move an object 1 DBP unit every 1/60th of a second regardless of the actual FPS.
Function TimeFactor(dwdFrameRate as DWord)
`Declarations
Dim dwdTimeStamp(0) as DWord
Dim dwdTimeDiff(0) as DWord
Local fltMS as Float = 0.0 `HI-res Ticks (originally miliseconds)
Local fltTF as Float = 0.0 `TimeFactor results
`Defensive coding (set default framerates
If dwdFrameRate=0 Then dwdFrameRate=60
`Calculate hi-res ticks required to achieve the desired framerate.
fltMS=15000000.0/dwdFrameRate
`Calculate the ratio between the actual time-span of the last update to the target framerate in hi-res ticks
fltTF=dwdTimeDiff(0)/fltMS
`Defensive programming...
`This caps the Virtual Framerate to 50% of the Actual Framerate to keep "jumping" from happening.
`2 = 200%, which is twice as many hi-res ticks.
`You can remark out or alter this line as needed.
If fltTF>2.0 then fltTF=2.0
EndFunction fltTF
`Call the Update_TimeFactor() once each frame, ideally after the Sync command.
`Do not use this function if using the TimeFactorSync() function (in the same loop)
#CONSTANT Update_TimeFactor Update_TimeFactor()
Function Update_TimeFactor()
`Declarations
Dim dwdTimeStamp(0) as DWord
Dim dwdTimeDiff(0) as DWord
`Defensive programming. Adjusts for the first time this function is called.
If dwdTimeStamp(0)=0 Then dwdTimeStamp(0)=PerfTimer()-16
`Calculate the Time Difference and set the new Time Stamp
dwdTimeDiff(0)=PerfTimer()-dwdTimeStamp(0)
dwdTimestamp(0)=PerfTimer()
Endfunction
`Use this function to include a sync command while updating the TimeFactor values.
`Do not use this function if using the Update_TimeFactor() function (in the same loop)
#CONSTANT TimeFactor_Sync TimeFactor_Sync()
Function TimeFactor_Sync()
`Declarations
Dim dwdTimeStamp(0) as DWord
Dim dwdTimeDiff(0) as DWord
`Call a screen update (Sync)
Sync
`Defensive programming. Adusts for the first time this function is called.
If dwdTimeStamp(0)=0 Then dwdTimeStamp(0)=PerfTimer()-16
`Calculate the Time Difference and set the new Time Stamp
dwdTimeDiff(0)=PerfTimer()-dwdTimeStamp(0)
dwdTimestamp(0)=PerfTimer()
Endfunction
Since these functions do not manage frame rate and the calculations are always based on the previous frame, there is the possibility of a jump occurring. There is some defensive code included to cap a jump, but it could still be noticeable if the frame rate suddenly changes dramatically. I would therefore consider using a frame-rate management function along with these functions in order to make the game movement as smooth as possible.
*Edit: After posting this I read TheComet's post. That is an excellent example of frame rate management code.