Bearbeiten: Ich habe das Problem behoben, indem ich die Sprunggeschwindigkeit so eingestellt habe, dass sie geändert und hinzugefügt wird, und die Geschwindigkeit gleich der Sprunggeschwindigkeit * t ist. Das habe ich gerade:
if (GUI->Space && grounded){
jumpvelocity = -185.f * 2 / gravity;
grounded = false;
}
if(!grounded ){
if(jumpvelocity < terminaly){
jumpvelocity += 185.f * t * 4 / gravity;
yvelocity = jumpvelocity * t;
}
else{
jumpvelocity = terminaly;
yvelocity = jumpvelocity * t / gravity;
}
}
else{
yvelocity = 0.f;
jumpvelocity = 0.f;
}
Danke für die Hilfe.
Ich versuche meine Schwerkraft zum Arbeiten zu bringen. Der Code, den ich bisher habe, ist
if (jumpvelocity < 0){
yvelocity = jumpvelocity * t *2/gravity;
jumpvelocity += 185.f*t * 2 / gravity;
}
else if(!grounded ){
if(yvelocity < terminaly)
yvelocity += t / gravity;
else
yvelocity = terminaly;
}
Die Schwerkraft steigt nach oben, je höher das Fallen und Springen langsamer wird. Der Standardwert ist 1. Die Sprunggeschwindigkeit ist auf 185 eingestellt, wenn der Spieler springen möchte. Mein Problem ist, dass Sie bei einer langsameren Framerate langsamer fallen, aber mit der gleichen Geschwindigkeit springen, als wäre es eine höhere Framerate. Wie würde ich es rahmenunabhängig machen? T ist die Deltazeit.
jumpvelocity
Beim Aktualisierenyvelocity
wird kein Mittelwert mit dem vorherigen Wert erstellt , was zu einem Genauigkeitsfehler führt, der sich bei niedrigerer Framerate verschlechtert. Was Sie nennen,yvelocity
sollte eigentlich sein,ymovement
da es sich um eine Geschwindigkeit multipliziert mit der Zeit handelt. Sie aktualisieren,jumpvelocity
wenn der Charakter den Boden nicht mehr berührt, was keine physische Bedeutung hat. Ihre Überprüfungterminaly
erfolgt vor dem Update, wasjumpvelocity
dazu führt , dass dieterminaly
Frameraten größer als und bei niedrigeren Frameraten schlechter werden.Antworten:
Bei jeder Hauptschleifeniteration:
currentTime
(z. B. SDL_GetTicks ())timeDelta = currentTime - lastTime
timeDelta
Sekunden konvertieren (normalerweise in ms oder ns), speichern alstimeDeltaSeconds
For each entity in entities: entity.position = velocityInUnitsPerSecond * timeDeltaSeconds
lastTime = currentTime
(könnte auch vor Schritt 1 statt hier erfolgen)... Sie müssen Ihre aktuellen Zahlen so einstellen, dass sie in Einheiten pro Sekunde angegeben sind, dh dass sie bei 1 FPS sinnvoll sind. Wenn Sie beispielsweise erwartet haben, dass die horizontale Geschwindigkeit Ihres Charakters 2 Pixel pro Zehntelsekunde beträgt, müssen Sie sie jetzt auf 20 Pixel pro Sekunde einstellen. Auf diese Weise funktioniert das oben Genannte korrekt.
Für einige Anwendungen ist es besser, den Zeitschritt auf einen bestimmten Wert festzulegen. In diesem Fall
timestep != timeDelta
. Letzteres ist die tatsächlich verstrichene Systemzeit. Ersteres ist eine quantisierte Menge, die Sie jedes Mal, wenn Sie logische Aktualisierungen in Ihrem Spiel anwenden, von Ihrem Zeitspeicher verbrauchen möchten. Dies unterstützt die Integration, wenn Sie iterative Löser verwenden, wie sie in den bekannten Physik-Engines zu finden sind, da die Zeitschritte bei der Berechnung gleich sein müssen. In diesem Fall bleibt nur ein Bruchteil der verbleibenden Zeit übrig , da Sie nicht einfach die gesamte verbleibende Zeit für jedes Tick verbrauchen, und Sie müssen diese für die Verwendung in späteren Ticks akkumulieren. Weitere Informationen hierzu finden Sie unter Fix Your Timestep von Glenn Fiedler.quelle
velocityInUnitsPerSecond
nur die Durchschnittsgeschwindigkeit während des verstrichenen Zeitrahmens. Wenn die Geschwindigkeit konstant ist, ist Ihr Code korrekt. Wenn sich die Geschwindigkeit linear ändert, wie dies bei der Schwerkraft der Fall ist, ist dieser Wert0.5 * (OldVelocity + NewVelocity)
. Andernfalls müssen Sie möglicherweise über einen kleineren Zeitschritt integrieren, um Genauigkeitsprobleme zu vermeiden.Es scheint überhaupt nicht
jumpvelocity
nötig zu sein. Springen bedeutet, die Geschwindigkeit sofort auf einen bestimmten Wert einzustellen: Sobald die Füße den Boden nicht mehr berühren, kann die Geschwindigkeit nur durch die Schwerkraft (und den Luftwiderstand, den Sie mit der Endgeschwindigkeit implementieren) geändert werden.Eine weitere Bemerkung: Gleitkommadivisionen sind extrem langsam. Ich schlage vor, Sie speichern
1.0f / gravity
stattgravity
.Schließlich besteht die Möglichkeit, dass für einen Frame
yvelocity
größer sein kann alsterminaly
.Mein Vorschlag:
Und denken Sie daran, dass Folgendes nicht korrekt ist:
Sie müssen tun:
quelle