# Issues calculating frame independent movement

I'm developing a Breakout style game in C++ using SDL. The problem so far is that the ball slows down and speeds up for no particular reason.

The slowdowns usually last a few seconds.

EDIT : When running fullscreen I noticed that the ball movement seems to be a tiny bit jerky as well. This leads me to believe that the timing should be more finely granulated. But at the same time, it shouldn't be necessary to have µs precision...

Here is my code for calculation the movement of the ball :

double deltaMovement = tick * speed;

rect.x += static_cast<int> ( deltaMovement * dirX );
rect.y += stnecessearyatic_cast<int> ( deltaMovement * dirY );


I tried changing it to help prevent float to in truncation, but this affects the speed to much, making the ball move only move horizontally or vertically ( which never happens with the above code. )

double movementX = ( deltaMovement * dirX );
double movementY = ( deltaMovement * dirY );

movementX += ( movementX > 0.0f )? 0.5f: -0.5f;
movementY += ( movementY > 0.0f )? 0.5f: -0.5f;

rect.x += static_cast<int> ( movementX );
rect.y += static_cast<int> ( movementX );


rect is an SDL_Rect and holds the ball's position. dirX and dirY are double and holds the direction of the ball, the values range from -1.0 to 1.0

I'm not sure if the issue is with the float to int conversion. I guess it could also be something with SDL internally, but I am quite sure SDL should be capable of smooth animation.

Here's my main game loop ( I have removed some irrelevant parts of it ) while ( !quit ) { while ( SDL_PollEvent( &event ) ) { // Handle input, move paddle, check if user pressed esc // Yes I have a means of escaping the outer while loop. } double delta = timer.GetDelta( );

    // Update the ball, check for collisions with wall/paddle/tiles
UpdateBalls( delta );

// Redraws everything
UpdateGUI();
}


I'm quite sure the issue is not with my delta time, since it's fairly consistant at 1 - 4 msec. And even if it did change a lot, it shouldn't matter. But just in case, here's the code I use for calculating delta time :

double Timer::GetDelta( )
{
timespec tmCurrent;
clock_gettime( CLOCK_MONOTONIC_RAW, &tmCurrent);

// Get current time in nanoseconds
unsigned long long deltaCurrent = static_cast< unsigned long long > ( tm.tv_sec * 1000000000 + tm.tv_nsec );

// Get diff. Delta is an unsigned long long that holds previous tick ( see below)
unsigned long long diff = deltaCurrent - delta;

// Convert into ms and assign to a double
double deltaMSec = static_cast< float > ( diff / 1000000.0f );

// Reset delta so that it can be used the next time delta is calculated
delta = deltaCurrent;

return deltaMSec;
}


What am I doing wrong?

• Where are deltaCurrent and delta coming from? If you've copy-pasted your timing code, then you're not updating the right variables. Aug 26, 2013 at 15:41
• @ShotgunNinja A copy-paste mistake. I have updated the question now. Aug 26, 2013 at 15:51
• Wow, that is an extremely unportable way of doing timing. If you want to be more portable, gettimeofday (...) provides enough resolution and granularity on all major *UX platforms your game is likely to run on (OS X, Linux, BSD). You should also use double-precision instead of single-precision FP for the deltaMSec. Aug 27, 2013 at 1:21
• Portbillity is not an issue right now. My plan was to add #ifdefs to add support for other platforms. Also gettimeofday (...)  seems to be hardware dependant : lehman.cuny.edu/cgi-bin/man-cgi?gettimeofday+3 I will change resolution to double, though. Aug 27, 2013 at 7:41
• clock_gettime (...) is also hardware-dependent. The only condition it adds (when using MONOTONIC) is that the value returned is always non-decreasing. This avoids issues with rdtsc-like instructions when the thread your timer is running on changes scheduled processors. However, despite being POSIX, it is not implemented on platforms like OS X. Also, MONOTONIC_RAW is a Linux-only extension. Aug 27, 2013 at 19:49

• I created my own struct that's basically the same as SDL_Struct but with double instead of short for storing position / dimension. It seems to be working, now. Thank you! Aug 27, 2013 at 20:27