Frame Unabhängig und Flüssige Bewegungen

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Mathias-Kwiatkowski

Betreff: Frame Unabhängig und Flüssige Bewegungen

BeitragDi, Jul 21, 2020 8:15
Antworten mit Zitat
Benutzer-Profile anzeigen
wie der titel schon sagt, ich habe z.b. mehrere Enemys diese bewegen sich alle frame unabhängig

Code: [AUSKLAPPEN]
Method Update:Int(PlayerEnemy:TEnemy = Null)
      Local Vergangen:Int = MilliSecs() - MoveTimer
      MoveTimer = MilliSecs()


nun ist es ja so das ein schleifendurchgang z.b. mal 3 ms dauert mal 15 (z.b.) was natürlich sofort ins auge fällt wenn eine einheit nicht 1 pixel nach dem anderen bewegt sondern ab und zu ein sprung macht, die frage ist wie löse ich dieses problem? also so das es flüssig laut anzeige ist?


edit
ich bin auf das hier gestoßen und wäre diese möglichkeit eine richtige?
https://www.blitzforum.de/foru...%C3%A4ngig
ich meine diesen code
Code: [AUSKLAPPEN]
Graphics 640, 480
SetBuffer Backbuffer()

While Not Keyhit(1)
StartZeit = Millisecs()
Cls

;Bewegen des Quadrats
Position = Position + (1 * SchleifenZeit)

;Wenn Quadrat ganz Rechts dann setze Quadrat nach ganz links
if Position > (640 - 16) then Position = 0

;Zeichnen des Quadrates
Rect Position, (240 - 8), 16, 16

Flip 0 ;60FPS Begrenzung ausschalten

SchleifenZeit = Millisecs() - Startzeit
Wend


EDIT 2

nein ich habe nun was ganz anderes erstellt. schaut mal und begutachtet es bitte
Code: [AUSKLAPPEN]
SuperStrict

Type TFPS
   Field Count:Int, Timer:Int, Frame:Int
   
   Method FPS:Int()
      Return Frame
   End Method
   
   Method Update()
      Count = Count + 1
      If MilliSecs() - Timer >= 1000 Then
         Timer = MilliSecs()
         Frame = Count
         Count = 0
      End If
   End Method
End Type

Function NewFPS:TFPS()
   Local F:TFPS = New TFPS
   F.Timer = MilliSecs()
   Return F
End Function

Function FPS:Int(F:TFPS)
   Return F.FPS()
End Function

Function UpdateFPS(F:TFPS)
   f.Update()
End Function

Type TVirtualFPS
   Field Timer:Int, Frame:Double
   
   Method Update:Int()
      If MilliSecs() - Timer >= Frame Then
         Timer = MilliSecs()
         Return 1
      End If
   End Method
End Type

Function NewVirtualFPS:TVirtualFPS(UpdatesPerSec:Int)
   Local V:TVirtualFPS = New TVirtualFPS
   V.Timer = MilliSecs()
   V.Frame = 1000 / UpdatesPerSec
   Return V
End Function

Function GetVirtualFPS:Int(V:TVirtualFPS)
   Return v.Update()
End Function


Local VirtualDrawFPS:TVirtualFPS = NewVirtualFPS(60)
Local VirtualUpdateFPS:TVirtualFPS = NewVirtualFPS(100)

Local FPS_0:TFPS = NewFPS()
Local FPS_1:TFPS = NewFPS()
Local FPS_2:TFPS = NewFPS()

Graphics 640, 480

Repeat
   UpdateFPS(FPS_0)
            
   If GetVirtualFPS(VirtualUpdateFPS) = 1 Then
      UpdateFPS(FPS_1)
      
   End If
      
   If GetVirtualFPS(VirtualDrawFPS) = 1 Then
      UpdateFPS(FPS_2)
      
      DrawText "Prog: " + FPS(FPS_0) + " Update: " + FPS(FPS_1) + " Draw: " + FPS(FPS_2), 15,15
         
      Flip 0
      Cls
   EndIf

   If AppTerminate() Then End
Forever


meine frage wäre nun nur was mach ich wenn die FPS bei updates nicht erreicht wird? weil z.b. das prog ja keine ahnung zuviel last hätte, oder was mach ich wenn der draw nicht erreciht werden kann? ich weiß nicht ob mein gedanke da utopisch ist, aber wenn was dann?

Edit 3
So leute glaube ich habe es nun richtig geschafft es läuft alles flüssig und frame unabhängig, habe allerdings eine aufwendige steuerung drin

user posted image

Was mache ich
Arrow Erst mal eine FPS klasse
Arrow Virtuelle FPS Klasse

Ich prüfe 3 fps werte einmal das gesamte programm
dann das für den update kram
dann das für die grafische ausgabe

in der update schleife ist eine atan2 funktion eingebunden (damit die ficher dort bewegbar zu position 0,0 sind) kann man anders machen aber ich wollte nun leistung absichtlich nutzen, um die virtuelle fps steuerung zu testen, ich habe desweiteren 8000 von den klein bildern in einer liste drin. es werden natürlich nur die "gemalt" die im sichtbereich ist, auflösung 1920,1080. demnach sind es ein paar wie man auf dem snap sehen kann.

jedenfalls prüft der virtuelle bereich nun wieviel FPS haben wir oh weniger als wir brauchen so wird mehr virtuelle leistung frei gegeben ( wenn noch welche zur verfügung steht ) ich prüfe dies einmal für den draw bereich und einmal für den update krempel.

die einheiten werden so gesteuert wie es sein sollte /fps vom update.

Code: [AUSKLAPPEN]
Local V:TVirtualFPS = New TVirtualFPS
   V.Timer = MilliSecs()
   V.Frame = 1000 / UpdatesPerSec
   V.SetFrame = UpdatesPerSec
   Return V


so lege ich meine virtuelle fps fest, also 1000(ms) / Das was erreicht werden soll.

und das wäre der code (ich weiß ihr seht nicht alles und das modul auch nicht, bei bedarf kann ich es auch hochladen.

Code: [AUSKLAPPEN]
AppTitle = "Pixel Orbit"
If Graphics (DesktopWidth() - 30, DesktopHeight() - 80) Then
   SetBlend ALPHABLEND
   TProgramm.ScreenWidth = Float(GraphicsWidth())
   TProgramm.ScreenHeight = Float(GraphicsHeight())
   
   Repeat
      Local MS:Int = MilliSecs()
      TProgramm.EnemyDraw = 0
      UpdateFPS(FPS_0)
      TProgramm.ProgFrameRate = FPS(FPS_0)
               
      If GetVirtualFPS(VirtualUpdateFPS) = 1 Then
         Local MS_UP:Int = MilliSecs()
         UpdateFPS(FPS_1)
         TProgramm.UpdateFrameRate = FPS(FPS_1)
         
         'Update Maus
         UpdateMouse()
         
         'PlayerUpdate
         UpdatePlayer()
         
         'Map Update
         LockMapList()
         For Local M:TMap = EachIn TStandart.MapList
            M.Update()
         Next
         UnLockMapList()
         TProgramm.UpdateMS = MilliSecs() - MS_UP
      End If
         
      
      If GetVirtualFPS(VirtualDrawFPS) = 1 Then
         Local MS_Draw:Int = MilliSecs()
         UpdateFPS(FPS_2)
         TProgramm.DrawFrameRate = FPS(FPS_2)
         
         'Map Draw
         LockMapList()
         For Local M:TMap = EachIn TStandart.MapList
            M.Draw()
         Next
         UnLockMapList()
         
         SetColor 0, 0, 255
         DrawRect 0, 0, 350, 90
         SetColor 255, 255, 255
         DrawText "Prog: " + ProgFrameRate() + " Update: " + UpdateFrameRate() + " Draw: " + DrawFrameRate(), 15, 15
         DrawText "Prog: " + ProgrammMS() + " Update: " + UpdateMS() + " Draw:" + DrawMS(), 15, 35
         DrawText "Enemy Showfield Draw: " + EnemyDraw(), 15, 55
         
         
         Flip 0
         Cls
         TProgramm.DrawMS = MilliSecs() - MS_Draw
      EndIf
      
      If DrawFrameRate() < FPS(FPS_2) Then ModifyVirtualFPS(VirtualDrawFPS, GetFrameVirtualFPS(VirtualDrawFPS) + 1)
      If DrawFrameRate() > FPS(FPS_2) Then ModifyVirtualFPS(VirtualDrawFPS, GetFrameVirtualFPS(VirtualDrawFPS) - 1)
      
      If UpdateFrameRate() < FPS(FPS_1) Then ModifyVirtualFPS(VirtualUpdateFPS, GetFrameVirtualFPS(VirtualUpdateFPS) + 1)
      If UpdateFrameRate() > FPS(FPS_1) Then ModifyVirtualFPS(VirtualUpdateFPS, GetFrameVirtualFPS(VirtualUpdateFPS) - 1)
      
      TProgramm.ProgrammMS = MilliSecs() - MS
      If AppTerminate() Or KeyDown(KEY_ESCAPE) Then End
   Forever

EndIf

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group