Четверг, 25.04.2024, 02:02
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Категории каталога
BlitzMax [14]
Blitz3D [9]
BlitzPlus [0]
Xna [1]
DarkBasic [0]
Общее [3]
Наш опрос
Hans Zimmer - что это для вас?
1. Где?
2. Композитор вроде
3. Простые символы
4. Любимый композитор
5. Я не определился
Всего ответов: 12
Форма входа
Поиск
Друзья сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Статьи
Главная » Статьи » BlitzMax

Стабилизация FPS в играх
В этой статье мы с вами разберёмся, для чего нужна стабилизация в играх и нужна ли она вообще. А так же какая стабилизация предпочтительнее, какие у неё есть минусы и плюсы.

Итак, для чего же нужна стабилизация в играх? У всех компьютеров разные вычислительные возможности, во всех компьютерах разная графическая подсистема, обладающая разной производительностью, поэтому наивно полагать, что игра на них будет идти с одинаковой скоростью и равномерно.

Те из вас кто пытался поиграть в старые игры для пентиум-1 и аналогичных наверняка сталкивались с проблемой чрезмерной резвости этих игр на вашем ПК, это связанно именно с тем, что в играх не было сделано элементарной стабилизации скорости выполнения игры на разных ПК.

А вот теперь другой пример, вы наверняка запускали «тяжелую» игрушку на своём ПК и она у вас заметно «тормозила» или весь игровой процесс напоминал сон из-за медлительных действий на экране. (Автор сам прошел GTA-3 на достаточно слабом ПК для неё, а потом спустя пару лет удивился тому, какой игра стала динамичной на новом ПК, оказывается, тогда я играл в сильно замедленном режиме по причине опять таки отсутствующей стабилизации).

Если вы не хотите, чтобы и ваша игра выкидывала такие вот фокусы, вам необходима стабилизация скорости выполнения игры.

Большой популярностью в среде Blitz-разработчиков игр пользуется следующий стабилизатор (код для BlitzMAX):
'stabilizator1.bmx
Const FPS:Int=75
Global period:Float=1000.0/FPS,elapsed:Int,Ticks:Int,tween:Float, time:Int

time=MilliSecs()-period
Repeat
Repeat
elapsed=MilliSecs()-time
Until elapsed

Ticks=elapsed/period
tween=Float(elapsed mod period)/Float(period)

For k=1 To Ticks
time=time+period
'############# C A L C U L A T I N G ###############
'logic code
Next
'###################### D R A W I N G ######################
'graphics code

Многие используют его не задумываясь, как он работает, а ведь часто это приводит к непредсказуемым последствиям. Давайте разберемся, что здесь к чему.

FPS – это максимально число кадров в секунду в вашей игре, стабилизатор не допустит превышение этого числа, что не даст вашей игре работать слишком резво.

Period – это расчётное время подготовки одного кадра в миллисекундах.

Elapsed – это фактически затраченное время на подготовку одного (прошлого) кадра в миллисекундах.

Ticks – необходимое число расчётов логики чтобы темп игры не отставал при низком fps от запланированного.

Time – расчётное время начала расчёта текущего кадра.
time=MilliSecs()-period

Эта строка инициализирует переменную time временем, когда должен был быть окончен расчёт предыдущего кадра.
Repeat
elapsed=MilliSecs()-time
Until elapsed

Смысл этого цикла в следующем, дождаться, когда затраченное время на расчёт кадра станет больше ноля. Теоретически время, затраченное на кадр всегда больше ноля миллисекунд, но на практике не все микропроцессоры обладают достаточной дискретностью таймера и/или не позволяют получать точное время с точностью до миллисекунды, поэтому иногда эта разница может быть и отрицательной. Вот для предотвращения возможных с этим ошибок и создан этот цикл. Он выполняется минимум 1 раз и вычисляет затраченное время на расчёт кадра, причём это время минимум 1мс.
Ticks=elapsed/period
tween=Float(elapsed mod period)/Float(period)

Здесь в первой строчке вычисляется отношение расчётного времени к реально затраченному на расчет прошлого кадра, число округляется до меньшего целого и это является коэффициентом ускорения всех движений в игре, чтобы запаздывающая графика успевала за темпом игры. Во второй строчке считается точный коэффициент для ускорения анимации.
For k=1 To Ticks
time=time+period
'############# C A L C U L A T I N G ###############
'logic code
Next

В этом цикле, который выполняется от 0 до Ticks раз, рассчитывается вся логика игры, именно внутри этого цикла нужно помещать AI, обновление положения игрока и юнитов и т.д.

Внутри цикла строчка "time+period" выполняет очевидную функцию – вычисляет расчётное время окончания этого кадра, естественно оно не совпадёт с фактическим, но именно это позволит сгладить эффект округления числа повторов логики до целого, за счёт постепенно нарастающей разницы между "time" и реальным временем.
'###################### D R A W I N G ######################
'graphics code
Forever

В этом, последнем куске кода размещается сам графический вывод изображения, т.е. очистка экрана, рендер мира и отображение заднего буфера. Так же здесь же располагаются команды вывода 2д графики и текста, однако нужно не забывать использовать их только после RenderWorld() (если используется 3Dграфика).

Плюсы данного стабилизатора:

* Честно выполняет свою роль, т.е. не даст вашей игре разогнаться больше допустимого, а так же скомпенсирует fps ступенчатостью движений.
* Простота использования

Минусы

* При текущем fps выше расчётного, число проходов логики равно нулю, что делает бесполезным следующий проход графики (т.к. на экране ничего не изменится).
* Стабилизация является неравномерной (т.е. не строго пропорционально замедлению графики), т.к. Ticks – целое число, из чего следует, что fps должен упасть в 2 раза, чтобы Ticks изменилось, и проходов логики стало 2 вместо 1. Поэтому происходит чередование кадров с удвоенным проходом логики и с обычным проходом логики. В результате на низких fps возможно неравномерное подергивание движущихся объектов.

Советы

* Пороговый fps лучше устанавливать как можно выше, это приведет к более плавным движениям, т.о. минимальное значение порогового fps должно быть не менее 75, а лучше его брать равным 1,5 желаемого fps в игре.

Целесообразность применения такой стабилизации становится под сомнение в свете следующих фактов:

* При экстремально низких пиковых реальных fps, отношение его к пороговому максимальному fps может достигать десятков. В результате на слабом ПК (по видео части) возникает противоречие, ЦП должен отработать десятки повторов логики чтобы сгладить запаздывание графики, что в свою очередь не оставит времени на расчет графики и еще усугубит ситуацию, ввергнув игр в пучину тормозов и лагов, это замкнутый круг.
* С другой стороны при реальном fps выше порогового, стабилизатор не даст логике игры выполняться, пропуская для части кадров расчет логики вообще. Но при этом выполнит графическую часть, что абсолютно бесполезно т.к. на экране ничего не изменится. Т.е. при превышении порогового fps начинается пустая трата процессорного времени и времени видеокарты на расчёт идентичных предыдущим кадров, в то время когда можно было бы дать им отдохнуть, тем более что работу под 100% нагрузкой долго не выдерживают особенно бюджетные видеокарты и ЦП.

Подводя итог этих фактов, следует признать большую полезность простого ограничителя кадров на базе ждущего таймера, т.к. он ограничивает fps и при превышении порогового fps даёт отдых как ЦП, так и видеокарте. Так же из-за отсутствия повторителя логики он позволяет игре выполняться чуть быстрее на слабых ПК по отношению к выше приведенному стабилизатору. Однако минусом его является снижение игрового темпа пропорционально падению fps.

Как компромисс возможно использование комбинированного стабилизатора, в котором при превышении порогового fps направляет ход выполнения программы на ждущий таймер, и разгружаем процессор, а при недостатке fps стабилизируем путём увеличения числа проходов логики. И ввести ограничение на число повторов логики, например до 5, и при превышении числа повторов логики сверх лимита не просчитывать пусть игра начнёт снижать темп. Это лучше чем лаги на высокой скорости.

Для аркадных же игр нетребовательным к вычислительной мощи ПК лучше обойтись ограничением fps на базе ждущего таймера настроенного на частоту около 50-60Гц.

Источник: http://blitzetc.boolean.name/articles/stab.htm

Категория: BlitzMax | Добавил: JohnK (07.06.2007) | Автор: SBJoker
Просмотров: 2713
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright JohnK© 2024