Smooth animation when using fixed time step

Posted by sythical on Game Development See other posts from Game Development or by sythical
Published on 2013-07-28T08:20:40Z Indexed on 2013/10/26 22:18 UTC
Read the original article Hit count: 343

I'm trying to implement the game loop where the physics is independent from rendering but my animation isn't as smooth as I would like it to be and it seems to periodically jump. Here is my code:

// alpha is used for interpolation
double alpha = 0, counter_old_time = 0;
double accumulator = 0, delta_time = 0, current_time = 0, previous_time = 0;
unsigned frame_counter = 0, current_fps = 0;

const unsigned physics_rate = 40, max_step_count = 5;
const double step_duration = 1.0 / 40.0, accumulator_max = step_duration * 5;

// information about the circ;e (position and velocity)
int old_pos_x = 100, new_pos_x = 100, render_pos_x = 100, velocity_x = 60;

previous_time = al_get_time();

while(true) {
    current_time = al_get_time();
    delta_time = current_time - previous_time;
    previous_time = current_time;
    accumulator += delta_time;

    if(accumulator > accumulator_max) {
        accumulator = accumulator_max;
    }

    while(accumulator >= step_duration) {
        if(new_pos_x > 1330) velocity_x = -15;
        else if(new_pos_x < 70) velocity_x = 15;

        old_pos_x = new_pos_x;
        new_pos_x += velocity_x;
        accumulator -= step_duration;
    }

    alpha = accumulator / static_cast<double>(step_duration);
    render_pos_x = old_pos_x + (new_pos_x - old_pos_x) * alpha;

    al_clear_to_color(al_map_rgb(20, 20, 40)); // clears the screen
    al_draw_textf(font, al_map_rgb(255, 255, 255), 20, 20, 0, "current_fps: %i", current_fps); // print fps
    al_draw_filled_circle(render_pos_x, 400, 15, al_map_rgb(255, 255, 255)); // draw circle
    // I've added this to test how the program will behave when rendering takes
    // considerably longer than updating the game.
    al_rest(0.008);
    al_flip_display(); // swaps the buffers

    frame_counter++;

    if(al_get_time() - counter_old_time >= 1) {
        current_fps = frame_counter;
        frame_counter = 0;
        counter_old_time = al_get_time();
    }
}

I have added a pause during the rendering part because I wanted to see how the code would behave when a lot of rendering is involved. Removing it makes the animation smooth but then I'll have to make sure that I don't let the frame rate drop too much and that doesn't seem like a good solution. I've been trying to fix this for a week and have had no luck so I'd be very grateful if someone can read through my code. Thank you!

Edit: I added the following code to work out the actual velocity (pixels per second) of the ball each time the ball is rendered and surprisingly it's not constant so I'm guessing that's the issue. I'm not sure why it's not constant.

alpha = accumulator / static_cast<double>(step_duration);
render_pos_x = old_pos_x + (new_pos_x - old_pos_x) * alpha;
cout << (render_pos_x - old_render_pos) / delta_time << endl;
old_render_pos = render_pos_x;

© Game Development or respective owner

Related posts about animation

Related posts about allegro