2013-06-23 14 views
5

Uso il delta time in modo da rendere indipendente la frequenza dei fotogrammi del programma. Tuttavia, non riesco a ottenere l'altezza di salto uguale, il personaggio salta sempre più in alto con una frequenza di fotogrammi inferiore.Come mantenere l'altezza di salto uguale quando si utilizza il tempo delta?

Variabili:

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

codice della logica:

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

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

sono sicuro che il tempo delta è corretto perché il personaggio si muove orizzontalmente bene.

Come faccio a far saltare il mio personaggio lo stesso indipendentemente dal frame rate?

+0

Quale unità/tipo è "delta"? –

risposta

6

La formula per calcolare la nuova posizione è:

position = initial_position + velocity * time 

Tenendo conto gravità che riduce la velocità in base alla funzione:

velocity = initial_velocity + (gravity^2 * time) 

NOTA: gravità in questo caso non è la stessa come la gravità. La formula finale diventa quindi:

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

Come si può vedere dalla precedente equazione, initial_position e initial_velocity non è affetto da tempo. Ma nel tuo caso hai effettivamente impostato la velocità iniziale uguale a -jumpVelocity * delta.

Più basso è il frame rate, maggiore sarà il valore di delta e quindi il personaggio salterà più in alto. La soluzione è quella di cambiare

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

a

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

EDIT:

Quanto sopra dovrebbe dare una buona stima, ma non è del tutto corretto. Supponendo che p(t) sia la posizione (in questo caso altezza) dopo il tempo t, quindi la velocità data da v(t) = p'(t)', and the acceleration is given by a (t) = v '(t) = p' '(t) `. Poiché sappiamo che l'accelerazione è costante; vale a dire la gravità, si ottiene la seguente:

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

Se ora calcoliamo p(t+delta)-p(t), vale a dire il cambiamento di posizione da un'istanza in tempo per un'altra otteniamo la seguente:

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 

Il codice originale non lo fa prendere in considerazione la quadratura di delta o il termine aggiuntivo g*delta*t*. Un approccio più accurato sarebbe quello di memorizzare l'aumento del delta e quindi utilizzare la formula per p(t) indicata in precedenza.

codice di esempio:

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; 
     } 
    } 
} 

NOTA: non ho compilato o testato il codice di cui sopra.

+0

Grazie! Anche se il codice di esempio non ha funzionato per me, dal momento che non avevo idea di dove verticaleVel entrasse in vigore. Tuttavia la tua risposta mi ha comunque aiutato a trovare la soluzione al mio problema. – user2513924

+0

Mi dispiace, ho perso quella linea. Non ha avuto effetto. Rimosso nel mio aggiornamento. – TAS

0

Per "delta time" intendi passi temporali variabili? Come in ogni fotogramma, calcoli un passo temporale che può essere completamente diverso dal precedente?

In caso affermativo, NON.

Leggi questo: http://gafferongames.com/game-physics/fix-your-timestep/

TL; DR: utilizzare passi temporali fissi per lo stato interno; interpola i fotogrammi se necessario.

Problemi correlati