I've been trying to implement the famous Fix your timestep in C++ and SDL2 using a simple example. I have a square that moves around on the screen but I cannot understand why it keeps jittering/stuttering sometimes when I run the application. By this I mean you can see the square "shaking" but it's very subtle.
My game loop is simply
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
{
init();
while (true)
{
update();
render();
}
return 0;
}
My update code is the following
template<typename T>
struct Vector
{
constexpr Vector() : x(0), y(0) {}
constexpr Vector(T x, T y)
{
this->x = x;
this->y = y;
}
// Linear interpolate between two vectors
static constexpr Vector lerp(const Vector& A, const Vector& B, double alpha) noexcept
{
assert(alpha >= 0.0 && alpha <= 1.0);
// A* t
Vector<float> lerpVectorA = A;
lerpVectorA.x *= alpha;
lerpVectorA.y *= alpha;
// B* (1.f - t);
Vector<float> lerpVectorB = B;
lerpVectorB.x *= 1.0 - alpha;
lerpVectorB.y *= 1.0 - alpha;
// A* t + B * (1.f - t);
return Vector(lerpVectorA.x + lerpVectorB.x, lerpVectorA.y + lerpVectorB.y);
}
T x;
T y;
};
// Timestep
static constexpr double dt = 1000.0 / (double)60;
static constexpr double maxFrameTime = 60;
double currentTime = 0;
double accumulator = 0;
double alpha = 0;
void update() noexcept
{
if (currentTime == 0)
{
currentTime = SDL_GetTicks();
}
auto const timeNow = SDL_GetTicks();
auto frameTime = timeNow - currentTime;
if (frameTime > maxFrameTime)
{
frameTime = maxFrameTime;
}
currentTime = timeNow;
accumulator += frameTime;
while (accumulator >= dt)
{
// Lerp
previousPosition = currentPosition;
// Move
currentPosition.x += xSpeed;
currentPosition.y += ySpeed;
if (currentPosition.x <= 0 || currentPosition.x > 640 - 64)
{
xSpeed *= -1;
}
if (currentPosition.y <= 0 || currentPosition.y > 480 - 64)
{
ySpeed *= -1;
}
accumulator -= dt;
}
alpha = accumulator / dt;
drawPosition = Vector<float>::lerp(previousPosition, currentPosition, alpha);
}
render()
simply renders the square on the screen at drawPosition
. Vysnc is enabled (so it runs at 60fps) but it doesn't make any difference if I disable it.
I can't see anything wrong in my implementation and I don't understand why it jitters/stutters sometimes.