Delta Timing - Constant game speed at any framerate.
Posted: Sat Apr 01, 2006 8:14 am
Okey someone requested this so I'm posting a small class and an example of how to use it.
If you were struggling with speed issues, this is your solution.
The class and example all together are quite old, I checked this a little and it should compile, if it doesnt, changes are minimal.
But I hope it helps someone... You can easily see the concept anyway.
Class\DeltaTime.pb
DeltaTime Example.pb
This implementation is quite good for 2D and 3D games as well, because it includes a weight idea I implemented some time ago, the idea is simple so I wont comment much about it. But basically the bigger your weight is, the smoother your graphics renderings will end up, but, the higher the values you'll need to move your sprites/entities.
I will post another example later showing how to use minimal CPU usage.
If you were struggling with speed issues, this is your solution.
The class and example all together are quite old, I checked this a little and it should compile, if it doesnt, changes are minimal.
But I hope it helps someone... You can easily see the concept anyway.
Class\DeltaTime.pb
Code: Select all
Structure FrameRate
TargetFPS.f
SpeedFactor.f
FPS.f
TicksPerSecond.l
CurrentTicks.l
FrameDelay.l
EndStructure
Global FL.FrameRate;
Procedure.l FrameLimitInit(target_FPS.f);
FL\TargetFPS = target_FPS;
FL\TicksPerSecond = 1000;
FL\FrameDelay = gettickcount_();
EndProcedure
Procedure.l SetSpeedFactor()
FL\CurrentTicks = gettickcount_();
FL\SpeedFactor = (FL\CurrentTicks - FL\FrameDelay) / (FL\TicksPerSecond / FL\TargetFPS);
If FL\SpeedFactor <= 0
FL\SpeedFactor = FL\TargetFPS* 0.001;
EndIf
FL\FPS = FL\TargetFPS / FL\SpeedFactor;
FL\FrameDelay = FL\CurrentTicks;
EndProcedure
;// Last modified: 01:40 a.m. 23/09/2005 | By GuShH_
DeltaTime Example.pb
Code: Select all
; delta timing in 2D (could be perfectly used on 3D or more dimensions ;) doesnt matter) - Sorry for the old code though!.
; by dagcrack
; Reason for this example is to show you how to use the
; DeltaTime Class...
;\\ Some basic stuff has been ripped off, we'll go to the grain on this example.
;\\ Although some parts are bloated, you'll be able to understand this easy concept.
;|>
;
;
;\\ Let's include the Delta Time class first...
IncludeFile "Class\DeltaTime.pb";
; And..
Structure ProgData;
WinWidth.w
WinHeight.w
WinTitle.s
WinID.l
Quit.l
EndStructure
InitSprite();
InitKeyboard();
Global P.ProgData
P\WinWidth = 640;
P\WinHeight = 480;
P\WinTitle = "DeltaTime Example | GuShH ";
hWnd.l = OpenWindow(#pb_any,0,0,P\WinWidth, P\WinHeight,13107201, P\WinTitle);
P\WinID = WindowID(hWnd);
OpenWindowedScreen(P\WinID,0,0,P\WinWidth, P\WinHeight,#null,#null,#null);
;- Our "game" stuff...
Structure Player
SprPointer.l
x.f
y.f
MoveFactor.f
EndStructure
Global Player.Player;
Procedure.l _CheckWinEvents();
EV = WindowEvent();
If EV = #PB_event_closewindow
P\Quit=#True;
EndIf
;SetWindowText_(P\WinID,P\WinTitle+Str(FL\FPS))
EndProcedure
Procedure.l _CheckKeyEvents();
ExamineKeyboard();
If KeyboardPushed(#PB_Key_Up);
Player\y - Player\MoveFactor;
EndIf
If KeyboardPushed(#PB_Key_Down);
Player\y + Player\MoveFactor;
EndIf
If KeyboardPushed(#PB_Key_Left);
Player\x - Player\MoveFactor;
EndIf
If KeyboardPushed(#PB_Key_Right);
Player\x + Player\MoveFactor;
EndIf
If KeyboardPushed(#PB_Key_Escape)
P\Quit=#True;
EndIf
EndProcedure
Procedure.l _CreateChar(Width.l, Height.l )
spr = CreateSprite(#pb_any,Width.l, Height);
StartDrawing(SpriteOutput(spr))
Circle(Width*0.5,Height*0.5,(((Width+Height)*0.5)*0.25),$0000FF)
StopDrawing()
ProcedureReturn spr
EndProcedure
Player\SprPointer = _CreateChar(64,64);
;-! SEE HERE
FrameRate = 150; Change this lower or higher, you'll see.
; It doesnt really matter anymore how fast the PC can render your game
; Everything will move as fast or as slow as it should.
GAME_FrameRate = 30 ; This is your game's internal "frame"rate!
FrameStep.f = (FrameRate*0.1); Don't change this... We are "weighting" the steps.
SetFrameRate(FrameRate);Set frame rate via PB.
FrameLimitInit(GAME_FrameRate/FrameStep); Init the delta-time system.
Player\MoveFactor = 1.4;
;-
DefType.f x,y;
;\\ Main loop
Repeat
; you might need to clear the screen though!
; the why I'm not clearing:
; the player sprite has big black surroundings...
; if the program "jitters", youll see red chunks on screen.
; (this helps you debug the delta time class).
SetSpeedFactor();
_CheckWinEvents();
_CheckKeyEvents()
; It's important to Multiply by the SpeedFactor!
x = x + Player\x * FL\SpeedFactor
y = y + Player\y * FL\SpeedFactor
; If you don't trust me, go ahead.. comment down the multiplys!
; That'd be like running without Delta Timing at all.
DisplaySprite(Player\SprPointer, x , y );
FlipBuffers(0);
Until P\Quit =#True;
I will post another example later showing how to use minimal CPU usage.