Seite 1 von 1

Delta Timing Modul

Verfasst: 10.03.2016 15:47
von gekkonier
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:

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

Re: Delta Timing Modul

Verfasst: 10.03.2016 15:59
von RSBasic
Danke gekkonier für deinen Code, der einfach, verständlich und klein ist. Sehr nützlich, wenn man ein Spiel programmieren möchte ohne FPS-Festlegung. :allright:

Re: Delta Timing Modul

Verfasst: 27.05.2016 20:40
von Sicro
Wird zum CodeArchiv unter Graphics/DeltaTiming.pbi hinzugefügt.