2
\$\begingroup\$

So ive read both http://gameprogrammingpatterns.com/game-loop.html and http://gafferongames.com/game-physics/fix-your-timestep/ and I kind of understand how I'm supposed to do it, but some parts are still blurry and I would like some guidance.

By the way, I have programmed my game from scratch and i do not want to change to some framework or anything that has an built in main loop, i want to do this by myself.

Anyway, this is what I have accomplished code-wise, I will re-produce my solution it in psudocode below.

func createPlayer()
{
oData = Empty Object()
oData.id
oData.name
oData.etc.....
Player = LoadSprite("filename", oData)
// Properties
Player.oSprite.x
Player.oSprite.y

Player.oSprite.scale
Player.oSprite.width
Player.oSprite.height
//Methods (Self-explanatory)
Player.oSprite.width()
Player.oSprite.height()
Player.oSprite.centerX()
Player.oSprite.centerY()

return Player
}

// Startup
oPlayer = createPlayer()
oWorld = 1D array of objects which has identical properties and methods from createPlayer()

// Main game loop
while(game){

 //User inputs 
 _game_userInputs(byref oPlayer)

 // "Physics" jumps and world collission is done here.
 _game_Physics(byref oWorld, byref oPlayer)

 // rendering, draws the world frame with all inputs and physics done beforehand
 _game_render(byref boWorld,byref oPlayer)

}

This is how I "understand" what flow the loop should have

t = 0.0
dt = 0.0
currentTime = 0.0
accumulator = 0.0

while(game)
{

  newTime = _Timer_QueryPerformanceCounter() // Im feeling like this need something more than just the QueryPeformenceCounter?
  frameTime = newTime - currentTime

  if (frameTime > 0.25) {
        frameTime = 0.25
  }
  currentTime = newTime

game_input()

//This is causing my game to get stuck here, i belive it has something to do with my type of timer
 while accumulator > dt
 {
  game_physics(t, dt) //how is the deltatime helping me in my physics?
  t += dt
  accumulator -= dt
 }

 alpha = accumulator / dt
  game_render(alpha) // I dont know what im supopsed to do with this.
}

TLDR, what do i do with the t, dt in my physics? before i render?

\$\endgroup\$
2
  • \$\begingroup\$ Do you need to do anything with them? \$\endgroup\$
    – user253751
    Feb 2, 2016 at 23:05
  • 1
    \$\begingroup\$ Your dt is zero. It is the constant, desired update interval; it is never calculated. That leads you into an infinite loop, as the accumulated time is never consumed. \$\endgroup\$
    – jmegaffin
    Feb 2, 2016 at 23:15

1 Answer 1

1
\$\begingroup\$

Let's go through this:

t = 0.0
dt = 0.0
currentTime = 0.0
accumulator = 0.0

Okay, som basic initialization, this is good. However, as Boreal mentioned, dt of 0 will cause problems. And since you are intending to fix your timestep, you should perhaps make dt a const and just set the value to whatever you want up here. Also, your currentTime initialization should probably be a timestamp of now or you will run into problems at the beginning of your program.

while(game)
{

  newTime = _Timer_QueryPerformanceCounter() // Im feeling like this need something more than just the QueryPeformenceCounter?

I'm not familiar with QueryPerformanceCounter since I'm not a windows programmer, but from the MSDN docs, it's not a time but instead a number of counts, which means you'll need to do some calculations using frequency.

  frameTime = newTime - currentTime

This is where your initialization of currentTime could cause problems. You want this to be a relatively small number always, and in the first cycle, you will get something large. In the aforementioned link, you can see that you actually need to initialize currentTime like QueryPerformanceCounter(&currentTime), and then at this point in the code, you would do the subtraction, but then also divide by the result of QueryPerformanceFrequency() to get an actual elapsed time that is system agnostic. If you don't then your loop will time differently on different systems that have different clock speeds.

  if (frameTime > 0.25) {
        frameTime = 0.25
  }
  currentTime = newTime

  game_input()

I wouldn't cap the resulting time, because that would cause some funky results with anything that uses the elapsed time in a calculation. If you intend to run this loop every 0.25 seconds, then that's how you'd set dt.

//This is causing my game to get stuck here, i belive it has something to do with my type of timer
 while accumulator > dt

The reason this is getting stuck is because dt is 0, which (depending on the value of accumulator) can either completely skip this block or get trapped inside this block because you are never actually modifying t or accumulator. I'm assuming you are setting your accumulator value to frameTime somewhere, because it's supposed to be the amount of time elapsed since the last action.

 {
  game_physics(t, dt) //how is the deltatime helping me in my physics?
  t += dt
  accumulator -= dt
 }

The value of dt is crucial to your physics, however, it should be a known constant value and shouldn't need to be passed around. This is what it means to have a fixed timestep. With that in mind, every calculation you do needs a timestep for things like acceleration updating velocity and velocity updating position, and any other timed physical effects counting down or up.

 alpha = accumulator / dt
  game_render(alpha) // I dont know what im supopsed to do with this.
}

alpha is the fraction of time you have left in a timestep and allows you to either interpolate results or simply save the accumulator for the next loop.

The effect of all of this is that you have fixed your timestep, but are allowing for the fact that your main loop won't run at exact multiples of your timestep. That's the point of the accumulator. It stores exactly how much time has passed since the last executed timestep, which is why you subtract a dt from it after every physics update; it is the mechanism by which you are actually fixing the timestep. There are also multiple ways in which to calculate current time, so I'll leave that up to you -- QueryPerformanceCounter does work (I'd think), but so would any number of other methods. The bottom line is that you want a fairly accurate timestamp or things can start to get jerky.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .