Animation and Keyboard

Velocity and Elapsed Time in a Simulation

Here is another variation of this program. This time, the cursor keys will be used to change the velocity of the ball (the speed of the ball, in other words). The velocity will be stored in a variable named v, and in the beginning it equals 0. The velocity represents how much the position of the ball changes on each iteration of the while loop. So, if the velocity equals 3, the ball will move 3 pixels to the right on each iteration of the while loop.

    int x = SCREEN_W/2;
    int v = 0;        
    while (!key[KEY_ESC]) {
        if (key[KEY_LEFT])
            v--;
        if (key[KEY_RIGHT])
            v++;
        x += v;
        clear_to_color(surface,makecol(255,255,255));      
        circlefill(surface,x,200,50,makecol(0,0,255));
        blit(surface, screen,0,0,0,0,SCREEN_W,SCREEN_H);
        rest(20);
        }
    return 0;

Let us consider this question: what is the actual speed of the blue ball? We said that the ball moves by a number of pixels given by variable v on every iteration, but how long does each iteration take?

We can certainly say that an iteration takes longer than 20 milliseconds, since the program is ordered to rest for 20 milliseconds on every iteration. Still, how much time do the other statements take to execute?

The clear_to_color and blit statements will take some non-negligible amount of time, since they have to process the entire drawing surface containing almost half a million pixels, where each pixel needs to be processed separately. The amount of time it takes depends on the speed of the computer executing the program. The only correct answer would be that the exact duration cannot be known in advance.

Try changing the argument of the rest function to observe the slowdown or speedup that may affect other computers.

However, the exact time of an iteration can be measured. Remember that the time at present, also called the current time, can always be obtained from the variable tickCount. In order to measure the duration of an iteration, all the program needs to do is to store, in a variable, the start time of previous iteration (measured in ticks). Then, to compute duration of previous iteration, measured in ticks, the program needs to subtract the start time of the previous iteration from the start time of current iteration which is equal to the time at present. It should then update the variable that stores the previous start time to reflect the time at present. Here is the code:

    int previousTime = tickCount;
    double x = SCREEN_W/2;
    double v = 0;        
    while (!key[KEY_ESC]) {
        int elapsedTimeInTicks = tickCount - previousTime;
        previousTime += elapsedTimeInTicks;
        if (key[KEY_LEFT])
            v -= 30;
        if (key[KEY_RIGHT])
            v += 30;
        x += v*elapsedTimeInTicks/1000.0;
        clear_to_color(surface, makecol(255,255,255));
        circlefill(surface,x,200,50,makecol(0,0,255));
        blit(surface, screen,0,0,0,0,SCREEN_W,SCREEN_H);
        rest(20);
        }
    return 0;

Notice that we had to make variables x and v to be of type double, as their values need to have precision higher than one pixel.

This program does pretty much the same thing as the previous one. However, the advantage of this program it that the ball will move at the same speed regardless of the speed of the computer running the program.

The variable v now contains the speed of the ball represented in pixels per second. The elapsedTimeInTicks variable measures the elapsed time of one iteration. It is calculated in the manner as previously described, by storing the current time of an iteration into the variable previousTime. The value of the variable previousTime will be used on the next iteration, when it will represent the time of the previous iteration.

Remember that one tick equals one millisecond. To calculate the elapsed time in seconds, the value of elapsedTimeInTicks must be divided by 1000. The program then multiplies the elapsed time (in seconds) by the velocity v (in pixels per second) to get the distance in pixels that the ball should be moved by. This is directly related to the equation of movement with uniform velocity used in physics that says:

  • x = x0 + vt

where x is the position at present, x0 is the previous position, v is the velocity and t is the elapsed time.

It was not a complete truth when we said that this program would move the ball at the same speed regardless of the computer running it. The previous program takes measures to ensure that the rate of change of the variable x is not affected by the speed of the machine that is executing the program. This still does not take account of the rate of change of the variable v. On a faster machine, the variable v will be changed more often than on a slower machine because iterations on a faster machine execute faster. To remedy this problem completely, a simple change will be sufficient:

        if (key[KEY_LEFT])
            v -= elapsedTimeInTicks;
        if (key[KEY_RIGHT])
            v += elapsedTimeInTicks;

Finally, we have made this program unaffected by the speed of the computer.