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.
Quale unità/tipo è "delta"? –