Есть ли способ программировать игры вне зависимости от частоты кадров?
Я программирую игру для iOS и использую метод update для многих вещей, который вызывается при обновлении скорости игры (на данный момент 60 раз в секунду), но проблема в том, что частота кадров падает (например, уведомление, или любое поведение в игре, которое при вызове заставляет немного опускаться fps...), тогда появляются ошибки...
Быстрый пример: если у меня анимация из 80 изображений, 40 для прыжка вверх и 40 для падения, мне понадобится 1,2 секунды для запуска анимации, поэтому, если переход занимает 1,2 секунды, все будет в порядке, анимация будет работать Но если мой fps упадет до 30, то анимация будет отключена, потому что для запуска анимации потребуется 2,4 секунды, а скачок останется 1,2 секунды. Это только быстрый пример, в игре много неожиданного поведения, если частота кадров падает, поэтому мой вопрос в том, сильно ли зависят разработчики игр от частоты кадров или есть способ избежать этих fps-ошибок? (другой способ программирования или какой-то трюк?)
3 ответа
Основывайте свое время на времени, а не на количестве кадров. Таким образом, сохраняйте отметку времени в каждом кадре, а в следующем кадре вычисляйте, сколько времени прошло, и на основе вашей идеальной частоты кадров выясните, сколько кадров анимации нужно продвигать. На полной скорости вы не должны заметить различий, и когда частота кадров падает, ваша анимация может работать рывками, но движение никогда не отстанет больше, чем на 1 кадр.
Редактировать: как указывает uliwitness, будьте осторожны, какую временную функцию вы используете, чтобы не возникало проблем, например, когда компьютер переходит в спящий режим или игра останавливается.
Всегда используйте дельта-значение в вашем методе обновления. Это не зависит от платформы и двигателя. Умножьте любую скорость или измените значение на значение дельты (временной интервал между текущим и последним кадрами).
В случае анимации одним из способов решения проблемы может быть умножение счетчика анимации на дельту (и инверсию ожидаемого интервала). Затем округлите это значение, чтобы получить правильное изображение для анимации.
// currentFrame is a float ivar set to 0 at the beginning of the animation.
currentFrame = currentFrame + delta * 60.0;
int imageIndex = roundf(currentFrame);
Тем не менее, в Sprite Kit есть лучший способ сделать такую анимацию, так как есть готовый SKAction, работающий со спрайтовой анимацией.
[SKAction animateWithTextures:theTextures timePerFrame:someInterval];
С этим решением вам не нужно иметь дело с синхронизацией изображений вообще. Двигатель сделает это за вас.
Здесь есть отличная дискуссия о методах FPS и Time:
Это лучшее, на мой взгляд, очень полное, простое для отслеживания и примеры JsFiddle. Я перевел эти примеры на C++ / Qt.
Нажмите здесь, чтобы посмотреть видео моего приложения: