2013-06-23 13 views
5

Ich benutze Delta-Zeit, damit ich meine Programm-Bildrate unabhängig machen kann. Allerdings kann ich die Sprunghöhe nicht gleich erreichen, der Charakter springt bei einer niedrigeren Bildrate immer höher.Wie halte ich die Sprunghöhe bei Delta-Zeit gleich?

Variablen:

const float gravity = 0.0000000014f; 
const float jumpVel = 0.00000046f; 
const float terminalVel = 0.05f; 
bool readyToJump = false; 
float verticalVel = 0.00f; 

Logic Code:

if(input.isKeyDown(sf::Keyboard::Space)){ 
    if(readyToJump){ 
     verticalVel = -jumpVel * delta; 
     readyToJump = false; 
    } 
} 

verticalVel += gravity * delta; 
y += verticalVel * delta; 

Ich bin sicher, dass die Delta-Zeit korrekt ist, weil die Zeichen horizontal fein bewegt.

Wie kann ich meinen Charakter unabhängig von der Bildrate gleich springen lassen?

+0

Welche Einheit/welcher Typ ist "Delta"? –

Antwort

6

Die Formel für die neue Position der Berechnung ist:

position = initial_position + velocity * time 

Unter Berücksichtigung der Schwerkraft, die die Geschwindigkeit entsprechend der Funktion reduziert:

velocity = initial_velocity + (gravity^2 * time) 

HINWEIS: Schwerkraft in diesem Fall ist nicht die gleiche als die Schwerkraft. Die endgültige Formel wird dann:

position = initial_position + (initial_velocity + (gravity^2 * time) * time 

Wie Sie aus der obigen Gleichung initial_position und initial_velocity sehen, ist nicht durch Zeit beeinflusst. Aber in Ihrem Fall setzen Sie die Anfangsgeschwindigkeit gleich -jumpVelocity * delta.

Je niedriger die Bildrate, desto größer wird der Wert delta und desto höher springt der Charakter. Die Lösung ist

if(readyToJump){ 
    verticalVel = -jumpVel * delta; 
    readyToJump = false; 
} 

zu

if(readyToJump){ 
    verticalVel = -jumpVel; 
    readyToJump = false; 
} 

EDIT zu ändern:

Die oben eine ziemlich gute Schätzung geben sollte, aber es ist nicht ganz korrekt. Unter der Annahme, dass p(t) ist die Position (in diesem Fall Höhe) nach der Zeit t, dann die Geschwindigkeit gegeben durch v(t) = p'(t)', and the acceleration is given by a (t) = v '(t) = p' '(t) `. Da wir wissen, dass die Beschleunigung konstant ist; dh Schwerkraft, erhalten wir folgendes:

a(t) = g 
v(t) = v0 + g*t 
p(t) = p0 + v0*t + 1/2*g*t^2 

Wenn wir jetzt p(t+delta)-p(t) berechnen, dh die Änderung der Position von einer Instanz in der Zeit zu einem anderen wir folgendes erhalten:

p(t+delta)-p(t) = p0 + v0*(t+delta) + 1/2*g*(t+delta)^2 - (p0 + v0*t + 1/2*g*t^2) 
       = v0*delta + 1/2*g*delta^2 + g*delta*t 

Der ursprüngliche Code nicht Berücksichtigen Sie die Quadratur von delta oder die zusätzliche Bezeichnung g*delta*t*. Ein genauerer Ansatz wäre es, den Anstieg in Delta zu speichern und dann die oben angegebene Formel für p(t) zu verwenden.

Beispielcode:

const float gravity = 0.0000000014f; 
const float jumpVel = 0.00000046f; 
const float limit = ...; // limit for when to stop jumping 

bool isJumping = false; 
float jumpTime; 

if(input.isKeyDown(sf::Keyboard::Space)){ 
    if(!isJumping){ 
     jumpTime = 0; 
     isJumping = true; 
    } 
    else { 
     jumpTime += delta; 
     y = -jumpVel*jumpTime + gravity*sqr(jumpTime); 
     // stop jump 
     if(y<=0.0f) { 
      y = 0.0f; 
      isJumping = false; 
     } 
    } 
} 

ANMERKUNG: Ich habe nicht kompiliert oder den Code oben getestet.

+0

Danke! Obwohl der Beispielcode für mich nicht wirklich funktionierte, da ich keine Ahnung hatte, wo verticalVel in Kraft trat. Aber Ihre Antwort hat mir immer noch geholfen, die Lösung für mein Problem zu finden. – user2513924

+0

Sorry, verpasste diese Zeile. Es hatte keinen Effekt. Entfernt es in meinem Update. – TAS

0

Mit "Delta-Zeit" meinen Sie variable Zeitschritte? Wie bei jedem Frame berechnen Sie einen Zeitschritt, der sich von dem vorherigen komplett unterscheiden kann?

Wenn ja, NICHT.

Lesen dieses: http://gafferongames.com/game-physics/fix-your-timestep/

TL; DR: feste Zeitschritte für den internen Zustand verwenden; interpolieren Frames bei Bedarf.