Полуфиксируемый или полностью фиксированный временной шаг?

15

Я делаю iphone shmup и пытаюсь решить, какой тип игрового цикла использовать. Я хочу использовать либо полуфиксированный временной шаг, либо полностью фиксированный временной шаг.

С полуфиксированным временным шагом я сделаю ноль или более вызовов update (FIXED_INTERVAL) с последующим одним вызовом update (dt), где dt <= FIXED_INTERVAL за цикл игры. Насколько я понимаю, недостатки этого метода заключаются в том, что мою логику обновления физики (dt) будет труднее программировать, потому что я в основном должен принимать переменную dt для каждого обновления. А потом я также услышал, что каждый запуск моей игры будет немного отличаться из-за того, что значения с плавающей запятой не всегда одинаковы.

Затем с полностью фиксированным временным шагом я делаю ноль или более вызовов обновления (FIXED_INTERVAL) с последующим одним интерполяционным вызовом (dt / FIXED_INTERVAL), где dt <FIXED_INTERVAL на цикл игры.

Поэтому мне кажется, что мне действительно нужно принять важное решение: хочу ли я решить задачу внедрения обновления (dt) с переменной dt или я хочу решить задачу реализации интерполяции?

Теперь из того, что я прочитал, большинство людей говорят использовать полностью фиксированную и выполнять интерполяцию. Но когда я думаю о реализации интерполяции, мне кажется, что я буду намного сложнее, чем обновление (dt) с переменной dt. Это потому, что если я использую интерполяцию, я должен помнить как предыдущее состояние, так и текущее состояние. Поэтому, если я хочу использовать интерполяцию, мне нужно придумать дополнительный уровень косвенности, который абстрагирует все отдельные состояния игры. В то время как с полуфиксированным временным шагом, когда мне не нужно использовать интерполяцию, мне не нужно придумывать абстракцию игрового состояния, потому что всегда есть только одно игровое состояние, и это просто «глобальные массивы», которые представляют моих врагов и врага пули и т. д.

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

Райан
источник
Покрыто довольно подробно здесь: gamedev.stackexchange.com/questions/1589/…
michael.bartnett
1
Я прочитал это обсуждение и ссылки там несколько раз. Это на самом деле, как я пришел к этому посту. Мой вопрос главным образом связан с тем, как реализовать игровые состояния для достижения интерполяции, что вообще не рассматривается в этом обсуждении.
Райан

Ответы:

12

Полностью исправлено

Вы теряете большинство преимуществ фиксированного временного шага, когда добавляете переменный шаг один раз в каждом кадре.

Ноэль Лопис отлично описывает, как он реализовал фиксированный временной шаг в своей игре Casey's Contraptions . В качестве бонуса для вас он разработчик iphone, хотя его техника не специфична для iphone.

Некоторые основные моменты из статьи

  • Используйте аккумулятор времени.
  • Используйте физическую частоту 120 Гц для частоты кадров 60 Гц.
  • Смоделируйте один фиксированный шаг в будущее и используйте накопление оставшегося времени, чтобы перехватить чертежный код между текущим физическим состоянием и будущим физическим состоянием.
  • различные ошибки
deft_code
источник
2

Что вы имеете в виду , как «полустационарный» и «полностью фиксированный» временного шаг, на моем взгляде, как фиксированный временного шаг - дт , что вы передаете на ваш updateвызов не меняются между кадрами.

Итак, ваш вопрос на самом деле "я хочу реализовать интерполяцию для целей рендеринга?" Ответ: вероятно нет .

Интерполяция - это то, что вы хотели бы делать, только если ваш фиксированный updateвременной шаг заметно отличается от целевого renderвременного шага. Нередко в играх с напряженной updateфазой можно вызывать только update, скажем, на 10 Гц, но рендерить на полной частоте кадров.

Так как вы пишете shmup для iPhone, ни ваши, updateни ваши renderпотребности не будут особенно загружать процессор; Вы можете легко зафиксировать частоту кадров на 30 Гц или 60 Гц, не заботясь о реализации, и при этом иметь гладкую игру.

Блэр Холлоуэй
источник
Я не понимаю Вы говорите, что я могу заблокировать большую ДТ, которую я вычислю в цикле игры - что потребляет моя физика? Как мне это сделать? Могу ли я сделать это с CADisplayLink? Я имею в виду, какой процент процессора вы используете? Должны ли вы действительно предполагать, что заблокирован игровой цикл DT?
Райан
То, что я говорю, на самом деле сводится к следующему: сделать наименее сложную вещь, которая будет работать.
Блэр Холлоуэй
1
Разработка: использование переменной dtдля updateи renderявляется самой простой вещью, которая будет работать, но обычно ее избегают, когда используют физические движки для нестабильности, которую она вызывает. Следовательно, вызов updateс фиксированной dtскоростью и рендеринг с одинаковой скоростью (при одновременном отбрасывании кадров при updateдлительных сеансах) - это, как правило, самая простая вещь, которая будет работать. Написание кода для интерполяции объектов между updateвызовами усложняет ваш код; сложность, которую вы добавляете, чтобы решить, в частности, никаких проблем.
Блэр Холлоуэй