Acceleration Independent Of Frame Rate


Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
I cant seem to get Acceleration or deceleration of a unit to move the same regardless of the frame rate.

If a key is pressed then a constant amount of force is added to xForce (or yForce) and then a force in the opposite direction is added to xForce based on the velocity (xVel/6).

The xForce is added to the units xVelocity which in turn is added to its x position proportional to the time since last update (t->x += t->xVel * moveAmount;).

This is the main code that iam using to move a unit.

CODE

int unit_move(struct unit *t)
{
int x;

struct unit *unitTemp;
struct unit *unitCurrent;

struct tile *tempTile = NULL;

float moveAmount;
int xdeceleration = 0;
int ydeceleration = 0;

moveAmount = (float)((gameTimer - t->speedTimer)/1000.0); // Get the amount of seconds past from previous movement

if(t->xVel != 0)
xdeceleration -= t->xVel/6;
if(t->yVel != 0)
ydeceleration -= t->yVel/6;

t->xForce += xdeceleration;
t->yForce += ydeceleration;

if((t->xVel > 0 || t->xVel < 0 ) && (xdeceleration) == 0)
{
t->xVel = 0;
}

if((t->yVel > 0 || t->yVel < 0 ) && (ydeceleration) == 0)
{
t->yVel = 0;
}

t->xVel += t->xForce;
t->yVel += t->yForce;

t->speedTimer = gameTimer;

t->xForce = 0;
t->yForce = 0;

t->x += t->xVel * moveAmount;
t->box.x = (int)t->x;

t->y += t->yVel * moveAmount;
t->box.y = (int)t->y;

return 0;
}



The unit has the same max velocity regardless of frame rate but its acceleration is still dependant on it. :(

I was wondering if anyone can see whats wrong or if i need to add anything?
 
Uprising said:
since last update (t->x += t->xVel * moveAmount;).
CODE

moveAmount = (float)((gameTimer - t->speedTimer)/1000.0); // Get the amount of seconds past from previous movement
Try moveAmount in milliseconds rather than in seconds. Otherwise, your code looks fine to me. I'm currently struggling with similar problems... maybe this will be a nice read for you: http://www.gaffer.org/game-physics/fix-your-timestep/.

Edit: Oh, I see you're using a float for moveAmount, so your code should work regardless...
 
Last edited by a moderator:
I did check if moveAmount was scaling proportionally to the frame rate and it is, so i dont think that is the problem.

Thanks for the link btw. The Integration Basics article also looks a good read.
 
Last time I had to write a game I used threads for handling the screen rendering, and the physics

so basically 1 thread for events, 1 thread for physics, 1 thread for graphics

That way, you can control the framerate and the physics independently ;)

But it was a simple game, and I'm a beginner ;)

*edit* to control speed, simply store the time at the beginning of the loop. At the end, compare it to the current time, and while the difference is less than what you want, wait by calling SDL_Delay
Do not make an empty loop "while (currentTime - initialTime < 50) {}" because it will run as fast as possible, taking maximum CPU power :)

Maybe you already know those tricks, but I don't know your level si this is just in case ;)
 
I have found out the problem!

I forgot that acceleration is meters per second per second, so I had to change the t->xVel += t->xForce; line to t->xVel += t->xForce * moveAmount;. But that ment i had to change some integers to floats and do another multiplication, damn you physics...

The tweening example may be what I need if it is running slowly thanks for that.

reiboul my level is definitely a beginner :p, I didnt know about waiting by SDL_Delay I guess it does make sense as the accuracy is only by milliseconds anyway.
 
Uprising said:
reiboul my level is definitely a beginner :p, I didnt know about waiting by SDL_Delay I guess it does make sense as the accuracy is only by milliseconds anyway.
Unfortunately it has its limits, in my game for example I'm beeing stuck at the point where 1ms is too much, and SDL_Delay can't do less than a millisecond :s So I want the game to go faster over time, but can't get faster when the time I want to wait for each loop is less than 1ms :(
 
Last edited by a moderator:
Back
Top