AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread GENAU alle 10ms ausführen

Ein Thema von Cubysoft · begonnen am 19. Aug 2015 · letzter Beitrag vom 23. Aug 2015
Antwort Antwort
Seite 2 von 3     12 3      
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#11

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 10:25
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:
TickCountAtStart:=gettickcount;
StepCount:=0;
und
nach jedem Durchlauf:
Code:
inc(StepCount,TicksPerStep);
sleep(TickCountAtStart+StepCount-gettickcount);
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 13:06
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;
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#13

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 20:59
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#14

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 21:35
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.

SleepEx function
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#15

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 21:57
Zitat: "Ich möchte aber dass der Thread immer 10 ms braucht."
Eben... Er hat nicht geschrieben: alle 10ms auch wenn meine Berechnung länger dauert...

Also gehe ich mal davon aus, das er schneller brechnet...

BTW..: ohne den Sleep schafft meine Pucman routine 480-550 Frames.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#16

AW: Thread GENAU alle 10ms ausführen

  Alt 21. Aug 2015, 08:07
@idefix2, @Mavarik: Siehe #5
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#17

AW: Thread GENAU alle 10ms ausführen

  Alt 21. Aug 2015, 11:19
Um noch einmal klar zu stellen was geschrieben wurde:
Dabei soll eine Berechnung genau alle 10ms ausgeführt werden und das in einem anderen Thread.
...
Problem ist nun halt, dass die Berechnung hierbei stark von dem benutzten PC abhängt. Wenn der Codeblock bei schnelleren PCs 5ms braucht, braucht er bei langsamen vllt 10. Ich möchte aber dass der Thread immer 10 ms braucht. Und nicht wie bei dem Beispiel 15ms oder 20ms..
Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#18

AW: Thread GENAU alle 10ms ausführen

  Alt 21. Aug 2015, 11:50
@idefix2, @Mavarik: Siehe #5
daher

So mach ich es auch...

Um noch einmal klar zu stellen was geschrieben wurde:
Logisch - Weil er in seinem Beispiel nicht die länge der Ausführung berücksichtigt hat und daher immer 10ms länger wartet...
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#19

AW: Thread GENAU alle 10ms ausführen

  Alt 21. Aug 2015, 15:11
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.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#20

AW: Thread GENAU alle 10ms ausführen

  Alt 22. Aug 2015, 03:15
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...)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz