Wie man Delta-Zeit bekommt und benutzt

13

Ich habe Mäuse, die in meinem Spiel schauen und laufen, aber sie sind sehr langsam und schwer zu bedienen. Ich denke, das liegt daran, dass ich eine feste Geschwindigkeit benutze. Ich habe gehört, dass Entwickler in großen Projekten Delta-Zeit verwenden. Wie berechne ich die Deltazeit in Glut? Wie berechne ich die Geschwindigkeit mit Delta-Zeit?

Mark Fedurin
quelle
C11 und C ++ 11 haben jetzt auch Nanosekunden-Uhren: stackoverflow.com/a/36095407/895245 || stackoverflow.com/a/5524138/895245
Ciro Santilli am

Antworten:

17

Die "Delta-Zeit" war die Zeit, die zwischen zwei Frame-Aktualisierungen verstrichen ist (sie kann jedoch auch in anderen Kontexten verwendet werden; dies ist normalerweise das Ergebnis einer Zeitsubtraktion).

Sie können die Deltazeit in glut mit der Methode glutGet und dem Parameter GLUT_ELAPSED_TIME sowie einigen Operationen abrufen.

Die folgende Zeile gibt die Anzahl der Millisekunden seit dem Aufruf von glutInit (oder dem ersten Aufruf von glutGet (GLUT_ELAPSED_TIME)) zurück:

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

Wenn Sie also die aktuelle timeSinceStart bei jeder Rendering-Schleife registrieren, können Sie die deltaTime ermitteln, indem Sie die alte von der neuen subtrahieren.

int oldTimeSinceStart = 0;

while( ... )
{
     int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
     int deltaTime = timeSinceStart - oldTimeSinceStart;
     oldTimeSinceStart = timeSinceStart;

     //... stuff to update using deltaTime
}

Sie können dies auch fast auf die gleiche Weise tun, indem Sie die C / C ++ - Zeitbibliothek mit clock () und den Makrokonstantenausdruck CLOCKS_PER_SEC verwenden , der die Beziehung zwischen einem Takt und einer Sekunde angibt.


Grundsätzlich können Sie deltaTime verwenden, um Ihre Bewegungen im Verhältnis zu dieser abgelaufenen Zeit zu aktualisieren, anstatt einen festen Zeitwert zu verwenden. Auf diese Weise sollte die Bewegungsgeschwindigkeit Ihres Charakters nahezu gleich sein, wenn Ihr Programm mit 60 fps oder mit 10 fps ausgeführt wird.


Hier ist ein kleines Beispiel: Angenommen, Sie möchten etwas um 10 Einheiten pro Sekunde auf der x-Achse verschieben. Sie könnten so etwas tun (wenn DeltaTime tatsächlich Millisekunden verwendet).

Position.x += 10/1000 * deltaTime;

Unabhängig davon, ob Ihr Programm 2-mal oder 100-mal aktualisiert wurde, sollte die Position 1 Sekunde später nahezu gleich sein, und das Gameplay wird durch die niedrigen FPS eines kleinen Computers weniger beeinträchtigt als bei Verwendung fester Werte.

  • Mit festen Werten ==> niedrige fps = weniger Updates = langsame Bewegungen, während hohe fps = mehr Updates = sehr schnelle Bewegungen.

  • Mit DeltaTime ==> "fast" die gleichen Bewegungen.


Schließlich sollten Sie auf gamedev.stackexchange Fixed time step vs Variable time step lesen .

Valkea
quelle
Gibt Millisekunden als Ganzzahl zurück? Gross und möglicherweise nicht ausreichend. Ich musste immer plattformspezifische Timer verwenden und habe dann GLUT wie die Pest einfach vermieden, da es für Spiele super nicht toll ist.
Sean Middleditch
@Sean Ich verwende auch kein GLUT, aber das war der Parameter der Frage, den ich in diesem Sinne beantwortet habe. Ich bin jedoch fasziniert von Ihrer Position in Bezug auf die "Unzulänglichkeit" von int, mit Millisekunden in Spielen umzugehen . Ein positive intAnstieg auf 2.147.483.647, wenn signiert, und auf 4.294.967.295, wenn nicht signiert. Selbst wenn wir den kleineren betrachten, sind 2.147.483.647 Millisekunden fast 25 Tage. Es sollte für die meisten Spiele ausreichen Timer und selbst wenn es nicht genug ist, können wir noch vernünftigerweise unsigned int(~ 50 Tage) oder sogar einen long long(wie ich es normalerweise tue) verwenden.
Valkea
1
@Valkea Der Punkt ist nicht das Maximum, sondern die Auflösung am unteren Ende. Da ein einzelner Frame bei 60 FPS nur 16 2 / 3rds ms beträgt, bedeutet eine Genauigkeit von 1 ms (von der Darstellung von Millisekunden als Ganzzahlen) eine Fehlertoleranz von mehr als 5% - mehr als genug, um Simulationen aus dem Ruder zu werfen. Eine ganzzahlige Anzahl von Mikrosekunden wäre erträglich, aber Millisekunden sind einfach zu grob.
Steven Stadnicki
Ja, Sie brauchen für viele Dinge ein Timing im Millisekundenbereich und einen hochauflösenden Timer, um das zu finden, was GLUT nicht bietet (von dem ich weiß). Es ist nicht schlecht, nur einen kleinen Plattformcode QueryPerformanceCounterfür Windows und die gettimeofdaymeisten anderen zu schreiben . Sie müssen sich die Hände schmutzig machen und etwas mehr als den kleinsten gemeinsamen Nenner von Plattform-APIs anstreben, insbesondere in C und C ++.
Sean Middleditch
Eine solche Präzision ist nicht für alle Spiele nützlich. Dies ist jedoch eine sehr interessante Erklärung, die meine Befragung zu Ihrer Sichtweise in Bezug auf int und clocks vollständig beantwortet. Ich habe noch nie eine hochpräzise Uhr gebraucht, aber ich denke, es ist an der Zeit, meine Kenntnisse zu vertiefen. Vielen Dank;)
Valkea