Hello!
I’ve recently started writing a simple 2D engine in order to gain some experience but my animations aren’t as smooth as I’d like them to be. I’m decoupled the physics from the rendering since I want to use the engine mostly for physics simulation. The game loop is described on this page under the ‘Free the physics’ section.
For testing, I have a texture moving left to right and vice versa at a constant speed and the application is rendering over 3000 frames per second and the animation is also quite smooth. I decided to add SDL_Delay(14) before SDL_RenderPresent(renderer) to see how the engine would behave at more realistic frame rates. The frame rate dropped to 71 as expected but the animation was no longer smooth. I first assumed that there is something wrong with my code and tried to finding a bug but had no luck. I started outputting the difference in the consecutive x-positions of the texture and the time difference between each render. Some of the output:
3 0.00993483
3 0.0100341
3 0.00998648
3 0.0100013
3 0.00999638
3 0.00998122
3 0.010053
Most of the output was very consistent and so I started searching for other issues. I decided to enable vsync and everything became as smooth as butter. This made me realise that if I’m rendering at 71 frames per second, 11 frames will be skipped and so the speed of the texture won’t look constant to the observer resulting in jerky animation.
So my actual question is: how to do so many games manage to have smooth animations at odd frame rates such as 62, 71, 83, etc. and should the frame rate be a multiple of the refresh rate?
Here is my game loop in case someone wants to read it:
while(main_event->type != SDL_QUIT)
{
last_time = current_time;
current_time = get_tick();
accumulator += current_time - last_time;
SDL_PollEvent(main_event);
if(accumulator > accumulator_max) {
accumulator = accumulator_max;
}
while(accumulator >= physics_step) {
if(pos_x_new < 101) vel_x = 3;
if(pos_x_new > 1300) vel_x = -3;
pos_x_old = pos_x_new;
pos_x_new += vel_x;
accumulator -= physics_step;
}
interpolation_value = accumulator / static_cast<double>(physics_step);
rect_data.x = pos_x_old + (pos_x_new - pos_x_old) * interpolation_value;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, rect_texture, NULL, &rect_data);
SDL_Delay(14);
SDL_RenderPresent(renderer);
}
My physics is updated at 60 Hz. Thank you for reading