У вас есть правильная базовая архитектура, в которой все должно быть обновлено в цикле, но вы должны сделать свой цикл намного умнее для игры (или другого приложения, требующего анимации OpenGL).
Однако мне нужно иметь возможность сделать паузу при нажатии клавиши.
Основной способ сделать это - получить логическое значение paused
и обернуть игру в цикл.
while(!finished) {
while(!paused) {
update();
render();
}
}
Как правило, однако вы все еще хотите делать такие вещи, как просмотр своего инвентаря, создание вещей и т. Д., Пока ваша игра приостановлена, и многие игры все еще выполняют свой основной цикл, пока игра приостановлена, они просто не позволяют актерам знаю, что время прошло. Например, кажется, что у ваших кадров анимации просто есть ряд игровых кадров, которые можно увидеть. Это плохая идея, потому что если скорость анимации увеличивается или уменьшается на другом компьютере, скорость анимации будет выглядеть неправильно на этих компьютерах. Вы можете рассмотреть мой ответ здесь и связанные примеры, чтобы увидеть, как можно добиться независимой от частоты кадров анимации, указав кадры анимации с точки зрения длительности в миллисекундах и передавая время кадра в цикле обновления. Например, ваша основная игра затем изменяется следующим образом:
float previousTime = 0.0f;
float thisTime = 0.0f;
float framePeriod = 0.0f;
while(!finished) {
thisTime = getTimeInMilliseconds();
framePeriod = previousTime - thisTime;
update(framePeriod);
render();
previousTime = thisTime;
}
Теперь все в обновленной игре будет знать, сколько времени прошло с предыдущего кадра. Это полезно для всех ваших физических расчетов, так как все наши физические формулы выражаются в терминах времени + начальные факторы + факторы затухания (например, уравнения SUVAT). Та же информация может использоваться для ваших анимаций, чтобы сделать их независимыми от частоты кадров, как я описал с некоторыми ссылками на примеры здесь .
Чтобы ответить на следующую часть вопроса:
it eats all of my cycles when the loop is going on.
Это потому, что вы используете 100% ЦП и никогда не спите. Если мы считаем, что мы хотим, например, 30 кадров в секунду на целевом устройстве (и мы знаем, что это возможно), то мы знаем, что период одного кадра составляет 1/30 секунды. Мы только что рассчитали время, необходимое для обновления и рендеринга нашей игры, чтобы мы могли спать в любое свободное время:
float previousTime = 0.0f;
float thisTime = 0.0f;
float framePeriod = 0.0f;
float availablePeriod = 1 / 30.0f;
while (!finished) {
thisTime = getTimeInMilliseconds();
framePeriod = previousTime - thisTime;
update(framePeriod);
render();
previousTime = thisTime;
if (framePeriod < availablePeriod)
sleep(availablePeriod - framePeriod);
}
Этот метод называется управлением частотой кадров, поскольку вы вручную контролируете скорость, с которой вы рендеринг и обновление.