1
\$\begingroup\$

I'm implementing my physics handler in my own 2D "Platform" game. My main problem is that when the timestep ( deltaTime ) changes, maybe to some tiny lag spike or something like that, the running entity visibly changes its speed ( running at top speed, actually) and that is really annoying to see. Other than that, if my game run slower (for example at ~33 fps) the entity moves definitely slower, which is, of course, not good at all, and moves 'lagging', in a completely not smooth way. I use a variable time step and I limit FPS only if I have to do some test (for example simulating lag). The game, and so the timestep calculation, is made with C++ and SDL2 but I think this issue is not language-specific. By the way this is how I calculate the timestep:

double last=0, delay=0;
while (running) {
    Uint32 now = SDL_GetTicks();
    if (now > last) {
        delay=now-last;
        last=now;
    }
    view->update(delay); // This is where every game logic takes place
    //... Do other stuff (clear screen, clear inputs, swap buffers)
}

Generally, this code works just fine, if my fps are less, then the deltaTime (delay in the code) increases. And that's ok. On the other hand there is a huge problem which is, of course, affecting my physic system: if my game runs faster than a certain number of fps (i.e. fps >= 1000 ) then, not matter what is the specific value, delay is always 1. This makes a game session running at 1000 fps fast 1/2 of a session running at 2000fps. I know those values are extremely high and that my game is running like that just because now it's empty, but I think I can't ignore this problem. What if a super high extreme gaming machine tries to run my game ?

Now let's talk about physics: My physics engine is really simple. It is 2D and, for now, I implemented only the x-Axis algorithm. My entity has a 2D vector holding speed (speed.x and speed.y ), a top speed (maxSpeed) and, of course, a position).

My engine works like this:

//Code executed in every frame:
if (fabs(speed.x) > 0 ) {
    speed.x /=  delta; //Simulate a very high friction

    if (fabs(speed.x) > maxSpeed) { //check if exceed the top speed
        //if so, set the speed to the top speed with the same sign
        speed.x = (maxSpeed * delta) * sgn(speed.x); 
    }

   //Finally change the position according to the speed
    x += speed.x*delta;
}

That is what I use to simulate a physic system, where sgn is custom function which returns 1 if the value is positive, -1 otherwise. I know the friction is very high, but at the moment I do not care too much.

The last piece of code I use, is the code to make the entity actually move. To do so I use this piece of code:

if (input->isKeyDown(KEY_D))
    speed.x += acceleration.x * delta;
else if (input->isKeyDown(KEY_A))
    speed.x -= acceleration.x*delta;

In this code acceleration is like a constant, it's simply a value. Now the code works fine in very general terms but the problems are:

  • Even a little change to delta (delay, variable time step) makes the entity visibly change his own speed (I guess it's related to top speed).
  • If my game runs on average of 30 -- 45 fps, the entity moves, but at a different top speed and the transition is verry laggy.
  • At a certain point delta becomes constant and that breaks up every physic logic.

I think everything is related to how I use my delta (delay) in each frane

\$\endgroup\$
  • 1
    \$\begingroup\$ The canonical answer to questions like these is an excellent article called Fix Your Timestep! \$\endgroup\$ – DMGregory Jan 6 '16 at 13:05
  • \$\begingroup\$ are you using SDL_Delay(delay); ? SDL_Delay only guarantees that the program will pause for at least "delay" time but it could wait a bit longer. \$\endgroup\$ – Joe Feb 1 '16 at 9:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.