Вы не должны полагаться на скорость рендеринга для своей игровой логики. Вместо этого следите за временем, проведенным с последнего логического шага в игре до текущего. Затем, если затраченное время превысило определенную сумму, вы выполняете игровой шаг (в редких случаях, когда компьютер работает так медленно, что должно было произойти два шага, вы можете придумать разумное решение, чтобы убедиться, не отстает).
Таким образом, игровая логика отделена от логики рендеринга, и вам не нужно беспокоиться об изменении скорости игры в зависимости от того, включена или выключена вертикальная синхронизация или компьютер медленнее или быстрее вашей. *
Какой-то псевдокод:
// now() would be whatever function you use to get the current time (in
// microseconds or milliseconds).
int lastStep = now();
// This would be your main loop.
while (true) {
int curTime = now();
// Calculate the time spent since last step.
int timeSinceLast = curTime - lastStep;
// Skip logic if no game step is to occur.
if (timeSinceLast < TIME_PER_STEP) continue;
// We can't assume that the loop always hits the exact moment when the step
// should occur. Most likely, it has spent slightly more time, and here we
// correct that so that the game doesn't shift out of sync.
// NOTE: You may want to make sure that + is the correct operator here.
// I tend to get it wrong when writing from the top of my head :)
lastStep = curTime + timeSinceLast % TIME_PER_STEP;
// Move your game forward one step.
}