Problem mit Timebased Movement [DEMO auf Seite 3]

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Code: Alles auswählen

__an_timerresolution.TIMECAPS
timeGetDevCaps_(@__an_timerresolution, SizeOf(TIMECAPS))
Debug __an_timerresolution\wPeriodMin ; gibt die Genauigkeit in ms an
timeBeginPeriod_(__an_timerresolution\wPeriodMin)

a = timeGetTime_() ; nun auf wPeriodMin genau

timeEndPeriod_(__an_timerresolution\wPeriodMin)
Mit diesem Code kannst du timeGetTime_() auf bei mir 1ms Genauigkeit
umstellen, noch genauer macht meist keinen Sinn.

greetz
Remi
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Sorry Remi, wenn ich dir widerspreche. Auf diese Art und Weise sind die Ergebnisse zwar wesentlich besser, es entstehen aber immer noch ruckler. Ich spreche aus Erfahrung bei meinem OGL Krempel. Da hab ich zwar 230 FPS, aber immer wieder zucker drinne. Ich hab also das gleiche Prob, wie ZeHa.

Vielleicht hilft das aber : Time Management
Optimismus ist ein Mangel an Information.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Dann mach halt ne FrameProc mit ca. 40 FPS. Ist einfacher und glaube
NFSU benutzt das auch (Aussage von nem Kollegen).

Oder versuchts mal mit Danilos Code, ist zwar das gleiche Prinzip, aber
ev. habt ihr ja etwas anders gemacht.

Code: Alles auswählen

;- Prozeduren 
Procedure InitGameTimer() 
  Shared _GT_DevCaps.TIMECAPS 
  SetPriorityClass_(GetCurrentProcess_(),#HIGH_PRIORITY_CLASS) 
  timeGetDevCaps_(_GT_DevCaps,SizeOf(TIMECAPS)) 
  timeBeginPeriod_(_GT_DevCaps\wPeriodMin) 
EndProcedure 

Procedure StopGameTimer() 
  Shared _GT_DevCaps.TIMECAPS 
  timeEndPeriod_(_GT_DevCaps\wPeriodMin) 
EndProcedure 

;- Globals 
Global PosX.f, PosY.f 
Global Timer.f, OldTime.f, TGT.f, Move.f 

;- Game init 
;SetRefreshRate(120) 

InitSprite() 
InitKeyboard() 
OpenScreen(1024,768,32,"") 

LoadSprite(0,"Bitmap.bmp") 
LoadSprite(1,"Hero.bmp") 

InitGameTimer() 
OldTime = timeGetTime_() 
;- Game loop 
Repeat 
  FlipBuffers() 
  ExamineKeyboard() 
  
  ; Berechnet 
  TGT     = timeGetTime_() 
  Timer   = TGT - OldTime 
  OldTime = TGT ; Verstrichene Zeit (75 * 5 = 375 pro 1000 Millisekunden -> .375 * Old 
  Move    = 0.375 * Timer 
  
  
  If KeyboardPushed(200) ; Up 
    PosY + Move 
  EndIf 
  If KeyboardPushed(208) ; Down 
    PosY - Move 
  EndIf 
  If KeyboardPushed(203) ; Links 
    PosX + Move 
  EndIf 
  If KeyboardPushed(205) ; Rechts 
    PosX - Move 
  EndIf 
  ; Ende Berechnet 
  
  If (PosX < -63) : PosX + 64 : EndIf 
  If (PosX >  63) : PosX - 64 : EndIf 
  If (PosY < -63) : PosY + 64 : EndIf 
  If (PosY >  63) : PosY - 64 : EndIf 
  
  For x = PosX - 64 To 1024 Step 64 
    For y = PosY - 64 To 768 Step 64 
      DisplaySprite(0,x,y) 
    Next 
  Next 
  DisplayTransparentSprite(1,512-32,384-32) 
  
Until KeyboardReleased(1) 

StopGameTimer() 

CloseScreen()
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Hellhound66 hat geschrieben:Ich spreche aus Erfahrung bei meinem OGL Krempel. Da hab
ich zwar 230 FPS, aber immer wieder zucker drinne.
Ein Multitasking-Betriebssystem schaltet ja immer zwischen
verschiedenen Prozessen hin und her.
Auch wenn Du keine externen Programmen laufen hast, das
Betriebssystem selbst läuft weiterhin und muß Verwaltungs-
aufgaben durchführen.

Bei solchen Frameraten ist das also kein Wunder wenn Du
das siehst, denn das umschalten dauert seine Zeit.
Je nachdem was noch so alles läuft, ist die kleinste Zeit auf
WinNT glaubich 5ms. Bei mehreren laufenden Prozessen
summiert sich das also und kann auch mal länger sein.

In dem obigen Code von mir hilft dabei die Erhöhung der
Priorität des eigenen Prozesses. Dadurch kann man diesem
Verhalten ein bissl entgegenwirken.
Mehr kann ich, ohne Code zu sehen, dazu aber erstmal
nicht sagen.

Frameraten von 230 oder mehr sind meist eh nicht nötig, wenn
der Monitor nicht auch mit dieser Bildwiederholfrequenz arbeitet.
Wenn der Monitor mit 115Hz arbeitet (als Beispiel), dann zeichnest
Du so jedes zweite Bild umsonst, da es der User nie zu sehen
bekommt.

Die Synchronisation mit dem Monitor macht also schon Sinn.
Dann läuft es bei einem User mit 60Hz, bei einem anderen
mit 120Hz. Durch das TimeBasedMovement ist die Spiel-
geschwindigkeit trotzdem bei beiden gleich schnell.
Frames die nicht angezeigt werden, weil das Updaten zu schnell
geht (z.B. 230FPS), kann man sich also sparen. Das frisst nur
unnötig Leistung und belastet das Multitaskingsystem somit
auch.
Zuletzt geändert von Danilo am 23.10.2005 15:30, insgesamt 1-mal geändert.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Was ich noch fragen kann/will, da Danilo hier ja mitliest:
Durch die Erhöhung der Priorität des Prozesses kommt es bei mir manchmal
im FullScreen zu Problemen bei der Keyboardabfrage von PB. D. h. es
verzögert die Tastendrücke ziemlich stark! Was kann man dagegen tun
und was ist genau der Grund?
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

remi_meier hat geschrieben:Was ich noch fragen kann/will, da Danilo hier ja mitliest:
Durch die Erhöhung der Priorität des Prozesses kommt es bei mir manchmal
im FullScreen zu Problemen bei der Keyboardabfrage von PB. D. h. es
verzögert die Tastendrücke ziemlich stark! Was kann man dagegen tun
und was ist genau der Grund?
Da der Source der PB-Libs nicht verfügbar ist, kann ich Dir
dazu nichts sagen. Bei PB funktioniert einiges ein bissl
anders als man das normalerweise kennt. ;)

Im DX7-Fullscreen setzt man normalerweise eh den exklusiven
Modus und erhöhte Priorität, Schau mal entsprechende Tutorials
an oder ins DX7-SDK, da solltest Du das sehen.
Würde das PB schon machen, hätte der obige Code keine
Veränderung zur Folge.

Wie das PB intern genau macht, können nur die Macher oder
die Sourcen davon sagen. Ohne das zu Wissen kann man
auch schlecht sagen wo es ein Problem geben könnte, denn
das kann ja überall sein.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Tja, schade. Trotzdem danke für deine Antwort!
:)
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

^^wäre das geklärt, zurück zum eigentlichen Thema bzw zu ZeHa :D

Das Zeitbasierte laufen ist ja eigentlich dazu da, das die Figur in einer X-Beliebigen Zeit eine bestimmte Distanz bewegt wird. Dabei ist natürlich klar, das die Distanz pro Frame immer Variiert. Das ist ja schließlich auch der grund, warum man dieses Model überhaupt benutzt. Wenn sich die Figur in jedem Frame X Pixel weit bewegen soll dann würde man das ja auch so machen. Dabei würde die Figur sich aber je nach PC-Geschwindigkeit in einer vorgegebenen Zeit X immer eine andere Distanz zurück legen.

Für mich sind Ruckler, wenn der Bildschirm kurz einfriehrt, sich also wirklich sichtbar keine Grafik mehr Bewegt. Das geschieht normal unter 30 FPS. Das wäre der Fall wenn z.B. die FPS eh nur bei 30 ist und dann sich plötzlich im hintergrund ICQ öffnet ... hierbei würde die FPS auf unter 10 rutschen und wenn ICQ vollständig geöffnet ist wieder hoch auf 30 gehen. (Natürlich nur wenn ICQ jetzt nicht noch veranlasst, den Fullscreen zu minimieren). Ruckler kann man auch als solche Definieren, wenn die FPS normal bei sagen wir 100 ist, und dann plötzlich kurzeitig auf 50 abfällt. Das hat aber normal keinen einfluss auf das Spiel selber, wenn die FPS anzeige nicht wäre würde man dies also nur schwer bemerken :wink: .

Als Ruckler verstehe ich aber überhaupt nicht, wenn man eh schon weit über 200 FPS hat und die Framezahl immer wieder auf 170 springen würde ... das hat keine einfluss auf das Spiel und ist für den Spieler selber auch nicht sichtbar, schon alleine wie Danilo ja schon schreib, durch die viel geringere Refreshrate eines Monitors.

Allerdings follgendes: Macht man einen Test mit seinem Programm, startet also quaise wirklich nur das Testprogramm und hat im Hintergrund wirklich rein garnichts laufen (dazu zählen auch z.B. sämtliche unnötigen Windowsdienste oder Antivirenprogramm), sollte die FPS Rate nicht regelmäßig stark fallen. Die definition von stark fallen würd ich sagen wir so als 25% und höher ansehen ... aber selbst das könnte immer noch am PC liegen und nicht am Quellcode selber. Zum testen kann man ja auch mal schnell eine kleine Schleife schreiben und dort die FPS Rate anzeigen lassen ... wenn hier genau so schwankungen auftrehten kann man sich spätestens jetzt sicher sein, das es am PC liegt :wink: .

Allerdings frag ich mich, wie ihr überhaupt sehen könnt, das sich ein Sprite mal 2 Pixel oder mal 5 Pixel bewegt? :wink: ... wenn ihr des wirklich sehen könnt, ist eher was im Code falsch ... wenn ihr des errechnet oder abgelesen habt, dann sollte ihr diese Werte mal nach der realität zurück rechnen ... den unterschied sieht man bei über 30 FPS nicht :wink: .
Ach ja noch was, beim Zeitbasierten Bewegt sich ein Sprite eher selten genau X Pixel weiter sondern eher hinter dem Kommer, nur auf dem Monitor können natürlich nur die stellen vor dem Kommer sichtbar gemacht werden :D

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Dabei ist natürlich klar, das die Distanz pro Frame immer Variiert
Falsch. Die Distanz sollte zwar auf jedem Computer anders sein, und auch mal variieren, wenn sich im Hintergrund irgendwas öffnet, aber im Regelfall sollte diese Distanz pro Frame immer genau gleich sein.

Es handelt sich zwar dann um keine glatte Zahl, aber dennoch sollte sie im Idealfall nicht in jedem Frame anders sein. Wenn sie z.B. um 0,005 schwanken würde, macht das natürlich nix, aber bei mir schwankt sie ja bereits zwiscehn 4,7 und 5,2 - und das merkt man in der Tat!

Wenn ich sie festsetze auf einen Wert, der zwar total krumm ist, aber somit jeden Frame wirklich gleich hoch ist, dann kann man von einem flüssigen Scrolling reden. Sobald der Wert aber ständig schwankt, zuckt alles hin und her. Und das ist wirklich ätzend, denn es handelt sich bei mir um ein Iso-Game. Dadurch ist das Scrolling natürlich schräg, und wenn da immer alles hin und her zittert, dann kriegt man da echt die Krise ;)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

@ZeHa:
Kannst Du mal einen lauffähigen Code zeigen wo man das Problem
sehen kann?
Da stimmt bestimmt irgendetwas mit Deinen Berechnungen nicht ganz.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten