Wednesday, November 18, 2015

c++ - How can I implement framerate-independant updates?


Edit: I fixed the problem by making jumpvelocity the one that is modified and added onto, and yvelocity just equal jumpvelocity * t. This is what I have right now:


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

Thanks for the help.



I am trying to get my gravity to work. The code I have so far is


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

Gravity scales upwards, the higher making falling and jumping slower. It's default value is 1. Jumpvelocity is set to 185 when the player wishes to jump. My problem is that you fall slower at a slower framerate, but you jump at the same speed as if it was a higher framerate. How would I make it frame independent? T is delta time.



Answer



On each main loop iteration:



  1. Check your system timer and store as currentTime (eg. SDL_GetTicks())

  2. timeDelta = currentTime - lastTime

  3. Convert timeDelta to seconds (usually it's in ms or ns), store as timeDeltaSeconds


  4. For each entity in entities: entity.position = velocityInUnitsPerSecond * timeDeltaSeconds

  5. lastTime = currentTime (could also be done before step 1 instead of here)


...You will need to adjust your current numbers to be in units per second, i.e. so that they would make sense at 1FPS. For example, if you expected your character's horizontal velocity to be 2 pixels per tenth of a second, then you now need to set it as 20 pixels per second. That way, the above will work out correctly.


For some applications, it is better to fix your timestep to a given amount. In this case, timestep != timeDelta. The latter is the amount of system time that has actually passed; the former is a quantised amount you want to consume from your time accumulator each time you apply logic updates in your game. This assists integration when you are using iterative solvers like those found in the well-known physics engines, because timesteps must be equal when doing the calculus. In this case, because you are not simply using up all of the time you have remaining on each tick, you will have fractions of time left over, and you need to accumulate these for use in later ticks. For more about this, read Fix Your Timestep by Glenn Fiedler.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...