Ich arbeite jetzt schon eine Weile an einem Projekt und bin kürzlich auf ein Problem gestoßen:
Der übliche Ansatz für die rahmenratenunabhängige Physik besteht darin, entweder ein festes Aktualisierungsintervall (dh Einheit) zu verwenden oder einfach jede physikalische Änderung mit Delta zu multiplizieren. Es würde also ungefähr so aussehen:
update(int delta)
{
...
positionX += velocityX * delta;
...
}
Und wenn die Beschleunigung hinzugefügt wird, wird die Geschwindigkeitsänderung ähnlich behandelt:
update(int delta)
{
...
velocityX += accelerationX * delta;
...
}
Dies funktioniert in den meisten Anwendungsfällen einwandfrei. In der Tat so gut, dass ich seit Monaten nichts mehr bemerkt habe. Es gibt jedoch ein Problem mit dieser Logik, nämlich dass die Position bei völlig unterschiedlichen Bildraten leicht abweicht. Dieses Problem ist bei der Arbeit mit kleinen Änderungen der Bildrate vernachlässigbar, macht sich jedoch vollständig bemerkbar, wenn sich die Deltazeit um größere Beträge ändert. Angenommen, die FPS-Rate liegt zwischen 30 und 600. In einem normalen Spiel sind die FPS nur gesperrt, und selbst wenn die Positionen für einige Frames um etwa 5% verschoben sind, spielt dies keine Rolle, da man es nicht bemerkt. Aber ich multipliziere das Delta manuell mit einem Faktor, um einen bestimmten Effekt zu erzielen, und der Fehler ist etwas auffällig und bricht das Spiel ab .
Ein kleines Beispiel, um zu verdeutlichen, was ich meine:
Es gibt ein Spielobjekt mit der Startposition posX = 0 und einer x-Geschwindigkeit von 10 und einer horizontalen Beschleunigung von 0,1.
Nach zwei Frames würde dies für 50 FPS zu (mit einem durchschnittlichen Delta) führen.
velocityX += acceleration * delta;
posX += velocityX * delta;
velocityX += 0.1 * 20; //velocityX = 12
posX += 12 * 20 //posX = 240
//next frame
velocityX += 0.1 * 20; //velocityX = 14
posX += 14 * 20 //posX = 520 (240 + 280)
Nach einem Frame mit 25 FPS, was dem gleichen Zeitintervall wie zwei Frames mit 50 FPS entspricht, erhalten wir Folgendes:
velocityX += 0.1 * 40; //velocityX = 14
posX += 14 * 40; //posX = 560
In zwei Situationen mit demselben Zeitintervall erhalten wir unterschiedliche Ergebnisse (520 für 50 FPS und 560 für 25 FPS).
Das Problem besteht nun offensichtlich darin, dass es einen zusätzlichen Frame gibt (in diesem Beispiel kann es sich um eine beliebige Anzahl von Frames handeln, die Ergebnisse unterscheiden sich jedoch für dasselbe Intervall), in dem die Beschleunigung angewendet wird und Sie daher mit weniger FPS weiter kommen.
Die Stabilisierung des Deltas ist keine Option, da ich für diesen Effekt unterschiedliche Deltas benötige. Daher muss die Physik dort völlig unabhängig sein. Hat jemand jemals eine ähnliche Situation erlebt und gibt es Lösungen dafür?