0
\$\begingroup\$

The problem :

I tried adding deltaTime into my game, which seems to not be working when I try to smoothly move a object in my game.

It currently looks like it "lag-jumps" across the screen.


How I calculate delta time :

Delta Time variables :

float elapsedTime = 0;
float lastFrameTimeElapsed = 0;
float deltaTime = 0;

At start of game loop I do this :

elapsedTime = SDL_GetTicks();

At end of game loop I do this :

deltaTime = elapsedTime - lastFrameElapsedTime;
lastFrameTimeElapsed = elapsedTime;

And then the game loop ends.


How I try to move my object using delta time :

My SDL_Rect variable :

Definition :

SDL_Rect* m_rect;

Initialization :

m_rect = new SDL_Rect();

My move function :

void Sprite::Move(float offsetX, float offsetY)
{
    m_rect->x += (int)offsetX;
    m_rect->y += (int)offsetY;
}

How I call the move function :

Move(5 * deltaTime, 0 * deltaTime);
\$\endgroup\$
  • \$\begingroup\$ You should ask about your account on meta. \$\endgroup\$ – Vaillancourt Mar 15 '16 at 18:02
  • \$\begingroup\$ Are you sure it forces you to use google? The email/password there are for any email, no? \$\endgroup\$ – Vaillancourt Mar 15 '16 at 18:06
  • \$\begingroup\$ (or perhaps contact stackexchange support) \$\endgroup\$ – Vaillancourt Mar 15 '16 at 18:07
  • \$\begingroup\$ We can't do anything about account merges, so yes, Biix should contact StackExchange directly via the contact us link at the bottom of any page and ask to have his accounts merged (and for whatever assistance is required in restoring access to the original account). \$\endgroup\$ – user1430 Mar 15 '16 at 18:09
  • 2
    \$\begingroup\$ "deltaTime = (elapsedTime - lastFrameTimeElapsed) / 1000;" What are the types of all these variables? This looks like potential integer division, which can result in "step like" movement. \$\endgroup\$ – user1430 Mar 15 '16 at 18:10
1
\$\begingroup\$

Consider the equation y=x, for x in the real numbers this equation is continuous. Our problem is that video game time is a piecewise, that is to say our line is actualy a series of distinct points. The more points over a given interval the closer you are to y=x. Thus you could decrease your step size (distance between points) to increase the number of points on a given interval. It might even be a good idea to make your step size a function of the change in time (delta-t) to have it account for variations in game loop time.

The granularity of SDL_GetTicks is milliseconds, instead of converting to seconds simply use it as is and change the scaling of your movement. This will remove floating point division and also probably the cause of your issue since your division is giving you whole seconds. If you want partial seconds change 1000 to 1000.0f assuming deltaTime is declared a float. If it is not, you might want to change that to increase the granularity of your calculations.

\$\endgroup\$
  • \$\begingroup\$ (I'm the guy that posted) This doesn't seem to work, I think it's because my rect only supports int values and I'm trying to add floats to it. And if I were to change it to a float (by making my own struct) I can't use the SDL_RenderCopy() function with the rect. \$\endgroup\$ – BiiX Mar 15 '16 at 20:57
  • \$\begingroup\$ Has to be floating point precision at least. Ints will be no use unless the int refers to millisecond values. Your own calculations will still necessarily be floating point calcs to ensure precise calculation of movement. \$\endgroup\$ – ManoDestra Mar 16 '16 at 20:39
1
\$\begingroup\$

You definitely need to integrate deltaTime into a float structure, but you can copy the newly modified location into an SDL_Rect for rendering. The player will still "teleport", but always and only by one, which may be acceptable in your game. My searches indicate that this is normal for SDL and the general solution seems to be to fallback on GL or DX and use orthographic projection to simulate the "2D" parts that benefit from floating point math.

deltaTime and all of your constants should also be floats; i.e. 1000.0f.

Scale:

Imagine driving a car with a speedometer labeled in integer "miles per minute". 60 MPH would be the only label "1". So you can drive at 1, faster than 1, or slower than 1. How do you put 0.833333333MPM (50MPH) on a speed-limit sign? Miles-per-minute is, clearly, not the most convenient scale for vehicle speed limits, even though both scales are equally accurate.

"Units per millisecond" is an equally undesirable scale because humans do not experience life as such.

  • "Carpe diem" - Seize the day, not the millisecond
  • "Day-to-day needs" - Again, days
  • "Tomorrow" - 86.4 million milliseconds from now
  • "Days of our lives" - Again, days
  • "Give me a minute" - 60,000 milliseconds
  • "Do it now; right this second" - 1000 milliseconds

Code:

Uint32 elapsedTime = 0; //Why not since SDL_GetTicks() returns Uint32
Uint32 lastFrameTimeElapsed = 0;

//Convert Uint32 milliseconds to float seconds
float deltaTime = (elapsedTime - lastFrameTimeElapsed) / 1000.0f; //Per-second is easy

Move(10.0f * deltaTime, 0.0f * deltaTime); //10 units per second

void Sprite::Move(float offsetX, float offsetY)
{
    //Moving 10 units per second at 60 FPS, yields offsetX/Y of +-0.1666666f
    //Since 0.1666666f rounds to 0, this won't work:
    //m_rect.x += roundf(offsetX);
    m_floatRect->x += offsetX;
    m_floatRect->y += offsetY;
    m_rect.x = roundf(m_floatRect->x);
    m_rect.y = roundf(m_floatRect->y);
}
\$\endgroup\$
  • \$\begingroup\$ I removed the / 1000.0f since it wasn't needed. And what's the difference between your post and just doing : m_rect.x = roundf(offsetX); on both x and y? \$\endgroup\$ – BiiX Mar 15 '16 at 22:09
  • \$\begingroup\$ @BiiX, offsetX and Y may be less than 0.5f due to deltaTime; rounding them to zero will not help. With floats, adding 0.1 multiple times will eventually amount to adding 1.0. You can't add 0.1 to an int. \$\endgroup\$ – Jon Mar 15 '16 at 22:13
  • \$\begingroup\$ @BiiX, be aware that, by removing the division by 1000.0f, your other constant 5000 becomes 5000 units per millisecond. Even more way-too-fast than before. I recommend keeping it because you will have fixed the precision error and will be able to think in "per second" terms which is more familiar to humans. \$\endgroup\$ – Jon Mar 15 '16 at 22:16
  • \$\begingroup\$ This does not seem to be the problem. Still got the same "laggy" movement. :/ \$\endgroup\$ – BiiX Mar 16 '16 at 7:40
  • \$\begingroup\$ @BiiX, how far do you currently teleport? The code should "snap" the user from pixel to pixel and that seems to be Working-As-Intended as far as sdl goes. \$\endgroup\$ – Jon Mar 16 '16 at 8:10

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.