![]() |
AW: Thread GENAU alle 10ms ausführen
Ich vermute, es geht dir darum, dass die Abläufe immer gleich schnell wirken. Dabei ist es relativ egal, ob der einzelne Durchlauf 8, 10 oder 11 ms nach dem vorigen Durchlauf erfolgt, aber Fehler dürfen nicht akkumulieren.
Zu Beginn:
Code:
und
TickCountAtStart:=gettickcount;
StepCount:=0; nach jedem Durchlauf:
Code:
inc(StepCount,TicksPerStep);
sleep(TickCountAtStart+StepCount-gettickcount); |
AW: Thread GENAU alle 10ms ausführen
So mach ich es auch...
Delphi-Quellcode:
procedure TMainTimeing.Execute;
var Timer : TStopWatch; MS : Int64; FPS : Single; begin Timer := TStopWatch.Create; Timer.Reset; while not(GameEnd) do begin try Timer.Start; GameScreen.Bereinigen; GameScreen.BeginUpdate; try try FPS := PacMan.NextFrame; except MS := 1; end; finally GameScreen.EndUpdate; end; TThread.Synchronize(NIL,Procedure() begin PacForm.BeginUpdate; try PacForm.Image1.Bitmap.Assign(GameScreen.Screen[GameScreen.AktScreen]); finally PacForm.EndUpdate; end; end); Timer.Stop; MS := Timer.ElapsedMilliseconds; Timer.Reset; if MS < FrameRate then Sleep(FrameRate-MS); except GameEnd := true; end; end; end; |
AW: Thread GENAU alle 10ms ausführen
Die Sache mit dem Sleep fällt jedoch komplett in sich zusammen, wenn der Code im Thread länger braucht als die maximale Sleep-Zeit nachher sein soll. Den negativen Wert kann man ja noch auf 0 clampen, aber wenn die gesamte Mechanik darauf ausgelegt ist, dass der Thread immer schneller als sein Intervall ist, bricht praktisch alles zusammen.
Ich gehe noch davon aus, dass es hier um die Frame-Update Methode geht, was der TE glaube ich noch nicht bestätigt hat: Der einzig richtige Weg ist es, die Framerate überhaupt nicht zu kontrollieren, das kann eigentlich nur schief gehen. Entweder man lässt es so schnell laufen wie es geht, oder, wenn man DirectX oder OpenGL einsetzt, man limitiert auf V-Sync. Der Kniff ist: Nicht die Framerate orientiert sich an der Spiellogik, sondern die Logik ist zeitlich skalierbar und an die Framerate anpassbar! Im Grunde muss man "nur" vorsehen, dass alle "Fortschritte", also alle zeitlichen Abläufe, ein gemeinsames Basisintervall annehmen, und dann einen Faktor entgegennehmen an den angepasst wird. Der Faktor ergibt sich dann aus der Verarbeitungsgeschwindigkeit von direkt davor. Damit bleiben alle Abläufe konstant, ganz egal wie schnell der PC ist. Man hat zwar potenziell ein Frame "Lag", da man immer auf den letzten anpasst (an den aktuellen geht ja nicht), aber im Mittel kommt das sehr gut hin, krasse Sprünge sind eher selten, und in der Gesamtheit passt es - ganz ohne kumulierte Fehler. Alles andere ist Gehampel, dass einem früher oder später um die Ohren fliegt. |
AW: Thread GENAU alle 10ms ausführen
Zitat: "Ich möchte aber dass der Thread immer 10 ms braucht."
Da kann man alles, was mit SLEEP() oder SLEEPEX() zu tun hat, vergessen. Es wird nur eine Mindestzeit "geschlafen", aber nach oben gibt es keine Funktionsgarantie, d.h. es kann auch mal 15,6 ms dauern, statt die gewünschten 1 bis 10. ![]() |
AW: Thread GENAU alle 10ms ausführen
Zitat:
Also gehe ich mal davon aus, das er schneller brechnet... BTW..: ohne den Sleep schafft meine Pucman routine 480-550 Frames. |
AW: Thread GENAU alle 10ms ausführen
@idefix2, @Mavarik: Siehe
![]() |
AW: Thread GENAU alle 10ms ausführen
Um noch einmal klar zu stellen was geschrieben wurde:
Zitat:
K-H |
AW: Thread GENAU alle 10ms ausführen
Zitat:
Zitat:
Zitat:
|
AW: Thread GENAU alle 10ms ausführen
Eine andere Variante wäre es, via Timer alle 10 ms die Aktion zu starten - wenn du dich darauf verlassen kannst, dass du in 10ms immer fertig wirst.
Wenn die Timer Routine noch läuft, wird allerdings der nächste Durchlauf übersprungen, während bei der Variante mit sleep der nächste Durchlauf sofort angehängt wird, und wenn ein Durchlauf im Schnitt nicht länger als 10ms dauert, die Verspätung aufgeholt werden kann. |
AW: Thread GENAU alle 10ms ausführen
Hier in der DP steht bestimmt schon mehrere hundert Male warum ein Timer für präzise Timings, vor allem unter 40ms/25ms komplett ungeeignet ist. Du bist doch schon lange dabei idefix, noch nie grüber gestolpert? (Davon ab wären auch "perfekte" Timer ungeeignet, zumindest wenn es wirklich um die Framerate in einem Spiel geht. Leider hat der TE das Thema hier offenbar schon verlassen, Nachfragen werden ja nicht beantwortet. Von daher...)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz