Basically I’m doing a basic game from scratch for fun, right now it is just a character running back and forth, jumping, parsing a heightmap and a scrolling background.
My main problem is that the background rolls very very choppy and I can’t seem to find why, so here’s how my main loop looks like:
double accumTimeMechanics = 0, accumTimeRender = 0;
mPreviousTime = M_Timer.ticks();
while (mIsRunning)
{
process_events();
/// current and previous get raw ticks, ticks are not in any time measurement
auto currentTime = M_Timer.ticks();
auto elapsedTime = M_Timer.elapsed_time(mPreviousTime, currentTime);
mPreviousTime = currentTime;
accumTimeMechanics += elapsedTime;
accumTimeRender += elapsedTime;
/// Prevents tunneling. The bigger the accumulated time, the more pixels the objects move per frame, hence we need to cap right before there is
/// a possibility of the collision system make objects pass through each other undetected. When this threshold is reached, the simulation will slow
/// down
if (accumTimeMechanics > MAX_MECHANICS_DELAY) {
accumTimeMechanics = MAX_MECHANICS_DELAY;
}
/// if accumulated time passed the minimum delay, it is time to update Mechanics
if (accumTimeMechanics > MIN_MECHANICS_DELAY) {
process_inputs(MIN_MECHANICS_DELAY);
update_mechanics(MIN_MECHANICS_DELAY);
play_sounds();
accumTimeMechanics -= MIN_MECHANICS_DELAY;
}
/// the renderer delay by default is half the Mechanics delay (giving 120 FPS), but it can be modified if added to a future "settings" in the game menu
if (accumTimeRender > MIN_RENDER_DELAY) {
update_graphics(MIN_RENDER_DELAY);
accumTimeRender -= MIN_RENDER_DELAY;
}
finish_loop();
}
The clock I use is SDL2’s, and I check to see if my system supports the correct resolution elsewhere.
The player will get movement proportional to the timestep like this:
process_inputs(const double elapsedTime)
{
////////////////////////////////// KEYBOARD INPUT /////////////////////////////////
auto kb = SDL_GetKeyboardState(NULL);
GPlayer::movX = (-kb[SDL_SCANCODE_A] + kb[SDL_SCANCODE_D]) * GPlayer::speed * elapsedTime;
///
}
The scrolling background is very simply
float leftX, rightX;
/// sum half the width because player starts at the middle of background
auto rollingPosX = std::fmod(GPlayer::posX + GGlobals::Width*0.5, GGlobals::Width);
leftX = -rollingPosX;
rightX = GGlobals::Width - rollingPosX;
SDL_FRect leftRect = {leftX, 0, GGlobals::Width, GGlobals::Height},
rightRect = {rightX, 0, GGlobals::Width, GGlobals::Height};
draw_background(leftRect, rightRect);
So, all variables involved are doubles, with the exception of the SDL_FRect which casts it to float. But that doesn’t seem to be the problem because integers can also be used, and moving to them doesn’t change the problem.
Am I overlooking something very basic here? The background seems to jump at random, sometimes even more noticeably, like it is trembling a bit, not smooth at all.
If I pass accumulated time directly it also won’t help, because there could be fluctuations in timing anyhow.
I’m not using any multithreading, this is just the most basic possible thing.
I can simplify that loop to get only on global accumTime and render along with the mechanics and other updates, but that also doesn’t help at all.
Hope someone could help shed some light on possible issues.
Thanks folks!