Delta Timing Modul
Verfasst: 10.03.2016 15:47
Auf verschiedenen Systemen - besonders wenn man sehr viele ressourcenintensive Dinge in seinem Spiel berechnet kann es sein, dass das Spiel unterschiedlich schnell abläuft.
Man kann messen wieviel Zeit während eines Durchlaufes des Mainloops vergangen ist und Transformationen mit dieser Differnz multiplizieren. D.h. Bewegungen, Rotationen, etc. kann man dadurch auf die selbe Geschwindigkeit bringen - egal wie flott das System ist.
Anbei ein kleiner Beispielcode, der das zeigt.
Wenn ihr im Code ;SetFrameRate(10) auskommentiert und mit dem Parameter rumspielt solltet ihr sehen, welchen Effekt diese Technik hat - der Text ruckelt dann zwar (simuliert einen sehr, sehr alten Computer), legt aber während der Zeit wo man die Cursortasten gedrückt haltet den selben Weg zurück.
wem das Delta::Delta(value) zuviel getippsle ist kann sich ja dafür ein Macro anlegen, auch das wird in dem Code demonstriert:
Man kann messen wieviel Zeit während eines Durchlaufes des Mainloops vergangen ist und Transformationen mit dieser Differnz multiplizieren. D.h. Bewegungen, Rotationen, etc. kann man dadurch auf die selbe Geschwindigkeit bringen - egal wie flott das System ist.
Anbei ein kleiner Beispielcode, der das zeigt.
Wenn ihr im Code ;SetFrameRate(10) auskommentiert und mit dem Parameter rumspielt solltet ihr sehen, welchen Effekt diese Technik hat - der Text ruckelt dann zwar (simuliert einen sehr, sehr alten Computer), legt aber während der Zeit wo man die Cursortasten gedrückt haltet den selben Weg zurück.
wem das Delta::Delta(value) zuviel getippsle ist kann sich ja dafür ein Macro anlegen, auch das wird in dem Code demonstriert:
Code: Alles auswählen
EnableExplicit
; BEGIN OF MODULE DELTA
; YOU CAN COPY THE WHOLE MODULE INTO A NEW FILE
; AND IncludeFile or XIncludeFile it instead!
DeclareModule Delta
EnableExplicit
Declare New() ; use this in front of your mainloop
Declare Measure() ; use this right at the end of your mainloop
Declare.f Delta(value.f) ; multiplies your value for cpu independent transformation
EndDeclareModule
Module Delta
Global oldtime.i
Global newtime.i
Procedure New()
oldtime = ElapsedMilliseconds()
newtime = ElapsedMilliseconds()
EndProcedure
Procedure Measure()
oldtime = newtime
newtime = ElapsedMilliseconds()
EndProcedure
Procedure.f Delta(value.f)
ProcedureReturn value * (newtime - oldtime)
EndProcedure
EndModule
Macro delta(value)
Delta::Delta(value)
EndMacro
; END OF MODULE DELTA
; example without any error handling!
InitSprite()
InitKeyboard()
Global x.f = 1024/2
Global y.f = 768/2
OpenWindow(0, 0, 0, 1024, 768, "Hello Delta", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, #True, 0, 0)
; Change parameter to test it out
;SetFrameRate(10)
Delta::New()
Repeat
; flush all window events
Repeat
Define event.i = WindowEvent()
Until event = 0
; handle input
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
End
EndIf
; without macro
If KeyboardPushed(#PB_Key_Left)
x = x - Delta::Delta(0.1)
EndIf
If KeyboardPushed(#PB_Key_Right)
x = x + Delta::Delta(0.1)
EndIf
; with macro
If KeyboardPushed(#PB_Key_Up)
y = y - delta(0.1)
EndIf
If KeyboardPushed(#PB_Key_Down)
y = y + delta(0.1)
EndIf
; draw
ClearScreen(RGB(0,0,0))
StartDrawing(ScreenOutput())
DrawText(x,y, "Use cursors to move me, press <esc> to quit.")
StopDrawing()
FlipBuffers()
Delta::Measure()
ForEver