# Accelerated Motion

I'm making a menu for my game with SDL, when you click on an option a sub menu slides down and is shown, just sliding down is really boring, so I want it to accelerate(like if gravity was pulling it) and bounce when it reaches the end. I don't care if it is physically accurate so I don't need exact 9.8m/s^2 acceleration, the acceleration I'm using is 1pixel/milisecond^2, now I don't really care about the final speed but I do need that it is always the same and that the animation takes always the same time, but my code doesn't, I perform a check on the speed at the end of the animation but It is not always the same, it is close though but just not the same, how can I make this last always exactly the same time and finish with the same speed?

float start_time = SDL_GetTicks();
float previous_time = start_time;
int speed = 500;    //500px/ms^2
int position = -569;

while(!return_button_clicked)
{
float current_time = SDL_GetTicks();
float elapsed_time = current_time - previous_time;
previous_time = current_time;

if(position < 0)   //if position the animation hasn't finished yet
{
speed += 1 * elapsed_time;     //I know the 1 is unnecessary
position += speed * elapsed_time / 1000;
if(position > 0)
{
position = 0;
}
if(position == 0)    //If it is at the bottom
{
while(speed > 0) //bounce back
{
current_time = SDL_GetTicks();
elapsed_time = current_time - previous_time;
previous_time = current_time;

speed -= 10 * elapsed_time;    //10 because I want the bouncing to be faster.
position -= speed * elapsed_time / 1000;
if(speed < 0)
{
speed = 0;
}
}
while(position < 0) //fall again
{
current_time = SDL_GetTicks();
elapsed_time = current_time - previous_time;
previous_time = current_time;

speed += 10 * elapsed_time;    //10 because I want the bouncing to be faster.
position -= speed * elapsed_time / 1000;
if(position > 0)
{
position = 0;
printf("final speed is: %d\n", speed); //if position is 0 the animation has finished(almost) so tell me the speed
printf("Time taken is: %d\n", SDL_GetTicks - start_speed);    //Tell me the time elapsed since the beginning.
}
}
}
}

checkForButtonsClicked();

if(!return_button_clicked)//if the user requested to go back, go back
{
while(position > -568)
{
/*Here, sometimes a negative speed is reached before
getting to the desired position
causing the menu to go in the
opposite direction, this doesn't
happen all the time but it is
unpredictable (to me at least),
so it means that it doesn't accelerate
and decelerate at the same pace always
also that's why it doesn't throw
the same speed value all the time.*/
speed -= 1 * elapsed_time;
position -= speed * elapsed_time / 1000;
}
}
}


Sounds like a job for an easing function! These are widely used to program animations, they are easy and flexible to use. An easing function usually takes an input between 0 and 1 (representing the progress of your animation, which plays from 0 to 1), and the output is also a number somewhere between 0 and 1, which you can use to multiply your position, or colour, or whatever it is you're animating.

Say you want to animate the movement of a variable y from y0 to y1, from start_time to end_time. You'll use an easing function like this:

time_interval = end_time - start_time;
y_interval = y1 - y0;
y = easing_function((time - start_time) / time_interval) * y_interval + y0;


From your description, it sounds like the easeOutBounce function will suit. Its output accelerates from start to end, but then bounces three times. There is a C implementation of the easing functions here: https://github.com/warrenm/AHEasing

You can use it as-is, or if you want to make your own custom function (such as a bounce that bounces less, or quicker), take a look at the code - it's fairly easy to understand.