Timebased Movement: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
K (Berechnung)
K (Bot: konvertiere/korrigiere HTML)
Zeile 21: Zeile 21:
 
Die wohl einfachste Möglichkeit unter Windows so etwas zu realisieren besteht darin mit Hilfe von GetTickCount die Zeit (in Millisekunden) seit dem letzen Windows-Start zu ermitteln.
 
Die wohl einfachste Möglichkeit unter Windows so etwas zu realisieren besteht darin mit Hilfe von GetTickCount die Zeit (in Millisekunden) seit dem letzen Windows-Start zu ermitteln.
  
  <font color="#000080"><i>//Benötigte Variablen</i></font>
+
  <font color="#000080">''//Benötigte Variablen''</font>
  <b>var</b>
+
  '''var'''
 
   BerechnungsZeit:LongWord;<br />
 
   BerechnungsZeit:LongWord;<br />
  <b>procedure</b> BeimStart;<font color="#000080"><i>//Was hier drinnen steht sollte zum Start ausgeführt werden</i></font>
+
  '''procedure''' BeimStart;<font color="#000080">''//Was hier drinnen steht sollte zum Start ausgeführt werden''</font>
  <b>begin</b>
+
  '''begin'''
   BerechnungsZeit := GetTickCount<b>()</b>;
+
   BerechnungsZeit := GetTickCount'''()''';
  <b>end</b>;<br />
+
  '''end''';<br />
  <b>procedure</b> BerechnungsCheck;<font color="#000080"><i>//Alle nötigen Berechnungen durchführen</i></font>
+
  '''procedure''' BerechnungsCheck;<font color="#000080">''//Alle nötigen Berechnungen durchführen''</font>
  <b>const</b>
+
  '''const'''
   Frequenz=1000;<font color="#000080"><i>//Durch Windows festgelegt</i></font>
+
   Frequenz=1000;<font color="#000080">''//Durch Windows festgelegt''</font>
  <b>var</b>
+
  '''var'''
 
   AktuelleZeit:LongWord;
 
   AktuelleZeit:LongWord;
  <b>begin</b>
+
  '''begin'''
   AktuelleZeit := GetTickCount<b>()</b>;
+
   AktuelleZeit := GetTickCount'''()''';
   Berechne<b>(</b><font color="#008000"><b>(</b></font>AktuelleZeit - BerechnungsZeit<font color="#008000"><b>)</b></font> /Frequenz<b>)</b>;
+
   Berechne'''('''<font color="#008000">'''('''</font>AktuelleZeit - BerechnungsZeit<font color="#008000">''')'''</font> /Frequenz''')''';
 
   BerechnungsZeit := AktuelleZeit;
 
   BerechnungsZeit := AktuelleZeit;
  <b>end</b>;<br />
+
  '''end''';<br />
  <b>procedure</b> Berechne<b>(</b>ZeitFaktor:Double<b>)</b>;
+
  '''procedure''' Berechne'''('''ZeitFaktor:Double''')''';
  <b>begin</b>
+
  '''begin'''
   <font color="#000080"><i>{Alle Berechnungen stehen hier }</i></font>
+
   <font color="#000080">''{Alle Berechnungen stehen hier }''</font>
   <font color="#000080"><i>//z.B</i></font>
+
   <font color="#000080">''//z.B''</font>
 
   Pos.X := Pos.X + Speed.X*ZeitFaktor;
 
   Pos.X := Pos.X + Speed.X*ZeitFaktor;
   <b>if</b> Pos.X > 20 <b>then</b> Pos.X := 0;
+
   '''if''' Pos.X > 20 '''then''' Pos.X := 0;
  <b>end</b>;
+
  '''end''';
  
 
=== Absolute Genauigkeit per Hardware ===
 
=== Absolute Genauigkeit per Hardware ===
 
Man kann auch die Hardware zur Zeitmessung nutzen um so noch genauere Ergebnisse zu erziehlen. Es kann jedoch theoretisch sein(auch jetzt noch?), dass diese nicht zur verfügung steht.
 
Man kann auch die Hardware zur Zeitmessung nutzen um so noch genauere Ergebnisse zu erziehlen. Es kann jedoch theoretisch sein(auch jetzt noch?), dass diese nicht zur verfügung steht.
  <font color="#000080"><i>//Benötigte Variablen</i></font>
+
  <font color="#000080">''//Benötigte Variablen''</font>
  <b>var</b>
+
  '''var'''
 
   BerechnungsZeit:Int64;
 
   BerechnungsZeit:Int64;
 
   Frequenz:Int64;
 
   Frequenz:Int64;
  <b>procedure</b> BeimStart;<font color="#000080"><i>//Was hier drinnen steht sollte zum Start ausgeführt werden</i></font>
+
  '''procedure''' BeimStart;<font color="#000080">''//Was hier drinnen steht sollte zum Start ausgeführt werden''</font>
  <b>begin</b>
+
  '''begin'''
   <b>if not</b> QueryPerformanceFrequency<b>(</b>Frequenz<b>) then</b><font color="#000080"><i>//Frequenz ermitteln</i></font>
+
   '''if not''' QueryPerformanceFrequency'''('''Frequenz''') then'''<font color="#000080">''//Frequenz ermitteln''</font>
     <b>raise</b> Exception.create<b>(</b><font color="#800000">'Kein Hardware Timer vorhanden'</font><b>)</b>;
+
     '''raise''' Exception.create'''('''<font color="#800000">'Kein Hardware Timer vorhanden'</font>''')''';
   QueryPerformanceCounter<b>(</b>BerechnungsZeit<b>)</b>;<font color="#000080"><i>//Aktuelle Zeit ermitteln</i></font>
+
   QueryPerformanceCounter'''('''BerechnungsZeit''')''';<font color="#000080">''//Aktuelle Zeit ermitteln''</font>
  <b>end</b>;
+
  '''end''';
  <b>procedure</b> BerechnungsCheck;<font color="#000080"><i>//Alle nötigen Berechnungen durchführen</i></font>
+
  '''procedure''' BerechnungsCheck;<font color="#000080">''//Alle nötigen Berechnungen durchführen''</font>
  <b>var</b>
+
  '''var'''
 
   AktuelleZeit:Int64;
 
   AktuelleZeit:Int64;
  <b>begin</b>
+
  '''begin'''
   QueryPerformanceCounter<b>(</b>AktuelleZeit<b>)</b>;
+
   QueryPerformanceCounter'''('''AktuelleZeit''')''';
   Berechne<b>(</b><font color="#008000"><b>(</b></font>AktuelleZeit - BerechnungsZeit<font color="#008000"><b>)</b></font> /Frequenz<b>)</b>;
+
   Berechne'''('''<font color="#008000">'''('''</font>AktuelleZeit - BerechnungsZeit<font color="#008000">''')'''</font> /Frequenz''')''';
 
   BerechnungsZeit := AktuelleZeit;
 
   BerechnungsZeit := AktuelleZeit;
  <b>end</b>;
+
  '''end''';
  <b>procedure</b> Berechne<b>(</b>ZeitFaktor:Double<b>)</b>;
+
  '''procedure''' Berechne'''('''ZeitFaktor:Double''')''';
  <b>begin</b>
+
  '''begin'''
   <font color="#000080"><i>{Alle Berechnungen stehen hier }</i></font>
+
   <font color="#000080">''{Alle Berechnungen stehen hier }''</font>
   <font color="#000080"><i>//z.B</i></font>
+
   <font color="#000080">''//z.B''</font>
 
   Pos.X := Pos.X + Speed.X*ZeitFaktor;
 
   Pos.X := Pos.X + Speed.X*ZeitFaktor;
   <b>if</b> Pos.X > 20 <b>then</b> Pos.X := 0;
+
   '''if''' Pos.X > 20 '''then''' Pos.X := 0;
  <b>end</b>;
+
  '''end''';
  
 
== Links ==
 
== Links ==
 
*[http://www.delphigl.com/script/do_show.php?name=bombman2&action=2 Bomberman DGL-Tutorial]
 
*[http://www.delphigl.com/script/do_show.php?name=bombman2&action=2 Bomberman DGL-Tutorial]

Version vom 3. Dezember 2005, 18:23 Uhr

Kurz-Beschreibung

Timebased Movement sorgt dafür, dass die Bewegungsgeschwindigkeiten nicht vom CPU-/Renderspeed abhängen.

Prinzip

Anstatt Bewegungs-Änderungen mit festen Werten durchzuführen, wird dieser Betrag vorher anhand der vergangenen Zeit berechnet. Dadurch wird verhindert das die Spielgeschwindigkeit an die Bildwiederholungs Frequenz gekoppelt ist.

Berechnung

Der Faktor um wieviel sich alles zu bewegen hat, kann zum Beispiel über die, seit der letzen Abfrage vergangen, Zeit ermittelt werden.

Allgemein:

VergangeneZeit:= (Zeit1-Zeit0)/Frequenz;

Diese vergangende Zeit(eigentlich immer in Sekunden oder Sekundenbruchteilen) ist nun der ZeitFaktor, den wir nutzen um zu bestimmen um wieviel sicht etwas bewegt.

Die Bewegung dann:

Position := Position + Geschwindikeit*VergangeneZeit;

Möglichkeiten

Millisekunden genau unter Windows

Die wohl einfachste Möglichkeit unter Windows so etwas zu realisieren besteht darin mit Hilfe von GetTickCount die Zeit (in Millisekunden) seit dem letzen Windows-Start zu ermitteln.

//Benötigte Variablen
var
  BerechnungsZeit:LongWord;
procedure BeimStart;//Was hier drinnen steht sollte zum Start ausgeführt werden begin BerechnungsZeit := GetTickCount(); end;
procedure BerechnungsCheck;//Alle nötigen Berechnungen durchführen const Frequenz=1000;//Durch Windows festgelegt var AktuelleZeit:LongWord; begin AktuelleZeit := GetTickCount(); Berechne((AktuelleZeit - BerechnungsZeit) /Frequenz); BerechnungsZeit := AktuelleZeit; end;
procedure Berechne(ZeitFaktor:Double); begin {Alle Berechnungen stehen hier } //z.B Pos.X := Pos.X + Speed.X*ZeitFaktor; if Pos.X > 20 then Pos.X := 0; end;

Absolute Genauigkeit per Hardware

Man kann auch die Hardware zur Zeitmessung nutzen um so noch genauere Ergebnisse zu erziehlen. Es kann jedoch theoretisch sein(auch jetzt noch?), dass diese nicht zur verfügung steht.

//Benötigte Variablen
var
  BerechnungsZeit:Int64;
  Frequenz:Int64;
procedure BeimStart;//Was hier drinnen steht sollte zum Start ausgeführt werden
begin
  if not QueryPerformanceFrequency(Frequenz) then//Frequenz ermitteln
   raise Exception.create('Kein Hardware Timer vorhanden');
  QueryPerformanceCounter(BerechnungsZeit);//Aktuelle Zeit ermitteln
end;
procedure BerechnungsCheck;//Alle nötigen Berechnungen durchführen
var
  AktuelleZeit:Int64;
begin
  QueryPerformanceCounter(AktuelleZeit);
  Berechne((AktuelleZeit - BerechnungsZeit) /Frequenz);
  BerechnungsZeit := AktuelleZeit;
end;
procedure Berechne(ZeitFaktor:Double);
begin
  {Alle Berechnungen stehen hier }
  //z.B
  Pos.X := Pos.X + Speed.X*ZeitFaktor;
  if Pos.X > 20 then Pos.X := 0;
end;

Links