AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Thread GENAU alle 10ms ausführen

Ein Thema von Cubysoft · begonnen am 19. Aug 2015 · letzter Beitrag vom 23. Aug 2015
Antwort Antwort
Dejan Vu
(Gast)

n/a Beiträge
 
#1

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 06:29
neben der Problematik, das du es so eh nicht hinbekommt, GENAU alle 10ms etwas auszuführen (wg. 'Sleep'), kann man bei längeren Intervallen durchaus so vorgehen:
Delphi-Quellcode:
while true do begin
  start := GetTickCount;
  DoSomething();
  Elapsed := GetTickCount - start;
  if Elapsed < TotalWaitingTime then Sleep (TotalWaitingTime - Elapsed);
end;
Du wartest also 'TotalWaitingTime' abzüglich der für den Berechnungsvorgang benötigten Zeit. Du kannst aber nicht davon ausgehen, das 'DoSomething' immer in exakt gleichen Intervallen aufgerufen wird. Kann ja sein, dass das OS kurz einen Schluckauf hat.

Daher musst Du deine Berechnungen (Zeitabhängige Bewegungen, schätze ich mal) so ausführen, das Du nicht das 'konstante' Intervall berücksichtigst, sondern die Differenz zwischen letzter Berechnung und jetzt. Dann laggt das Spiel zwar vielleicht immer noch, aber wenigstens sind die Bewegungen gleichförmig.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.879 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 07:11
Dabei muss man aber beachten, dass Windows nur bedingt echtzeitfähig ist.
Markus Kinzler
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.185 Beiträge
 
Delphi 12 Athens
 
#3

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 07:22
Zitat:
dann lieber ein eigener Treiber per DDK im Kernelmode und es wird realistisch beherrschbar.
Da würde ich schon eher so ein fertiges Realtime-System einsetzen, das sollte es auch hinbekommen.
http://www.kithara.de/de/produkte/realtime-suite
Ob sich das einfach installieren lässt weiss ich nicht, es scheint sich tief in den Unterbau von HAL einzuklinken, und dein Windows ist womöglich nicht mehr das was es mal war.

Aber wie schon zuvor gesagt: Für ein Spiel ???

Könnte aber sein das manche Spiele soetwas nutzen ?


Rollo
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#4

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 07:47
Und warum sollte man keinen Timer nehmen?

Code:
function timeSetEvent; external mmsyst name 'timeSetEvent';
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.688 Beiträge
 
Delphi 12 Athens
 
#5

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 07:53
Da würde ich schon eher so ein fertiges Realtime-System einsetzen, das sollte es auch hinbekommen.
http://www.kithara.de/de/produkte/realtime-suite
Für zeitkritische Steuerungsaufgaben (PLC, CNC) ist das schon ein wirklich gutes Produkt. Allerdings nehmen die Herrschaften auch Lizenzgebühren pro Installation, die locker mit dem Preis für die meisten "großen" PC-Spiele mithalten können. Ich wage deshalb mal die Behauptung, daß kein PC-Spiel diese Engine einsetzt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#6

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 09:22
Idealerweise verzichtet man heutzutage auf feste Framerates. Man misst man die Zeit des letzten Schrittes und berechnet quasi, was in der Zeit passiert ist.
Wenn ein festes Zeitraster aus technischen Gründen für dein Spiel wirklich nötig ist, dann kannst du das von der Ausgabe entkoppeln (die vermutlich die meiste Zeit frisst). Nur wenn noch Zeit ist oder eine bestimmte Zielframerate unterschritten wird, kann ein neues Bild gerendert werden.
  Mit Zitat antworten Zitat
idefix2

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

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 09: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.157 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 12: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.688 Beiträge
 
Delphi 2007 Enterprise
 
#9

AW: Thread GENAU alle 10ms ausführen

  Alt 20. Aug 2015, 19: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
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 19:42 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-2025 by Thomas Breitkreuz