2D платформеры: почему физика зависит от частоты кадров?

12

«Super Meat Boy» - это сложный платформер, недавно вышедший для ПК, требующий исключительного контроля и идеального прыжка в пикселях. Физический код в игре зависит от частоты кадров, которая установлена ​​на 60 кадров в секунду; это означает, что если ваш компьютер не может запустить игру на полной скорости, физика сойдет с ума, в результате чего (среди прочего) ваш персонаж будет работать медленнее и падать сквозь землю. Кроме того, если vsync выключен, игра работает очень быстро.

Могут ли те, кто имеет опыт программирования 2D-игр, объяснить, почему игра была написана таким образом? Разве физический цикл, работающий с постоянной скоростью, не будет лучшим решением? (На самом деле, я думаю, что физический цикл используется для частей игры, так как некоторые из сущностей продолжают нормально двигаться независимо от частоты кадров. С другой стороны, ваш персонаж работает точно [fps / 60] так же быстро.)

Что меня беспокоит в этой реализации, так это потеря абстракции между игровым движком и графическим рендерингом, которая зависит от системных особенностей, таких как монитор, видеокарта и процессор. Если по какой-либо причине ваш компьютер не может справиться с vsync или не может запустить игру со скоростью ровно 60 кадров в секунду, он впечатляюще сломается. Почему шаг рендеринга должен каким-либо образом влиять на физические расчеты? (В настоящее время большинство игр либо замедляют игру, либо пропускают кадры.) С другой стороны, я понимаю, что платформеры старой школы на NES и SNES зависели от фиксированной частоты кадров для большей части их управления и физики. Почему это так, и можно ли создать патформер в этом ключе, не имея зависимости частоты кадров? Обязательно ли происходит потеря точности, если вы отделяете рендеринг графики от остальной части движка?

Спасибо, и извините, если вопрос был запутанным.

Archagon
источник
Касательно вашего вопроса. Вот отличная статья, которая охватывает именно те проблемы, которые вы описываете, и «правильный» способ обработки временных шагов и частоты кадров. gafferongames.com/game-physics/fix-your-timestep
num1
Меня действительно удивило, что они так поступят. Я предполагаю, что это должно быть потому, что он был построен в основном для консоли, где можно полагаться на частоту кадров. Неудовлетворительно!
Иэн

Ответы:

7

Почему?

Горстка причин, сделай свой выбор: они не знали ничего лучше. Это быстрее и проще в реализации. Они были сосредоточены больше на игровом процессе и меньше на крайних случаях, которые могут не возникнуть в большинстве случаев.

Вы довольно хорошо объяснили, почему нет. Я уверен, что вы заметили, что есть много тем, которые охватывают эту тему . Я не уверен, что вы найдете удовлетворительный ответ помимо тех, которые я перечислил.

тетрада
источник
«Они не знали ничего лучшего» описывает, почему я выбрал такой подход с «Джек - дурак». Но - я сильно полагался на вызов dt со времени последнего кадра со всей моей логикой. Но - с координатами с плавающей точкой, это может привести к некоторым странным, трудно копируемым ошибкам
lochok
4

Изначально SMB был консольной игрой, в которой можно с уверенностью предположить, что он способен работать со скоростью 60 кадров в секунду на всех Xbox360 (ну, может быть, 50 для некоторых игроков PAL). Предполагая, что фиксированный временной шаг упрощает код довольно много.

Хотя многие вещи легко масштабировать с помощью переменного временного шага - «pos + = скорость * временного шага», довольно сложно сделать это правильно, когда вы имеете дело с ускорениями, скоростями изменения ускорения и так далее.

Разделение игрового процесса и рендеринга - хорошее теоретическое решение , но реализовать его хорошо (с хорошей интерполяцией) довольно сложно, и вещи могут легко запутаться. Этот метод довольно редко используется в реальных играх (хотя некоторые крупные игры делают это, особенно в играх RTS, но больше для синхронизации сетевых игр).

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

bluescrn
источник
1

Очевидное решение состоит в том, чтобы иметь 2 параллельных цикла - рендеринг каждые 1/60 секунды и игровой цикл каждые 1/60 секунды.

Но с моим опытом во Flash (AS3, в котором я уверен, что Super Meat Boy был создан), планировщик не всегда очень точен. Точность также сильно зависит от окружающей среды. В автономном флеш-плеере он может иметь разрешение менее миллисекунды. Но при запуске в некоторых веб-браузерах точность становится частотой кадров.

Таким образом, самый близкий способ, которым вы можете добраться до разделения рендеринга и игровых логических циклов, - это чтобы все движения были основаны на времени (и запускали каждый кадр на основе того, сколько времени прошло с последнего кадра). Это может привести к некоторому усложнению математики (например, применять гравитацию непрерывно, а не увеличивать скорость объекта через заданные интервалы). Поскольку игра может отставать на секунду, а затем ваш игрок будет двигаться на 200 пикселей за один шаг, обнаружение столкновений и реагирование могут стать еще более сложными. Если бы программист делал обнаружение коллизий по кадрам (проверяя коллизию на каждом временном шаге), им также пришлось бы переключаться на обнаружение коллизий по времени. И если бы они хотели, чтобы это казалось естественным, им пришлось бы использовать метод гравитации, описанный выше, который заставляет движение объекта быть кривой (в противоположность линии),

Ponkadoodle
источник
2
Оригинальный Meat Boy был флеш игрой. Super Meat Boy - это игра на C ++.
Archagon
0

Я не думаю, что слишком много просить, чтобы 2D-игры для ПК играли со скоростью 60 кадров в секунду. Даже большинство 2D-игр теперь аппаратно ускорены, так что лично я бы не беспокоился о требовании fps.

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

Если вы делаете игру, основанную на физике (возможно, бросание птиц?), Ответ очевиден, но клон Супер Марио? основанное на времени движение может быть немного большим.

PhilCK
источник
Несложно воспроизвести их при 60 кадрах в секунду, но дисплеи с собственной частотой обновления 50 Гц, 70–85 Гц и 120 Гц все еще легко найти.
0

Чтобы избежать странного поведения в двумерной физике, которую они используют?

Честно говоря, я могу только догадываться. Я попробую объяснение:

В основе игры лежит основной игровой цикл. Который в основном выглядит так:

while(gameRunning)
{
  updateGame(timestep);
  renderGame(timestep);
}

updateGame обновляет gameState: проверяет ввод игрока, применяет ввод игрока в игровой мир, запускает симуляцию физики и т. д.

renderGame рисует и оживляет игру.

Это связывает обновление физики с рендерингом. Если вы хотите отделить его, вам нужно будет использовать потоки и правильно синхронизировать каждый доступ к данным рендеринга и потока gameUpdate с общими данными, например позицией игрока. Это можно сделать.

Другая проблема может заключаться в том, что физическое моделирование требует постоянного временного шага для стабильной работы. Это зависит от того, как supermeatboy рассчитывает движение (Опять же, мы можем только догадываться, как они это сделали;)).

Наивный подход был бы (который я использую в своей игре * вздох *):

position=position+speed*timestep;
speed=speed+acceleration*timestep;

Это называется интеграцией Эйлера и, как правило, считается плохой идеей. Если временной шаг не постоянен, возникают ошибки вычисления, которые делают симуляцию менее стабильной. Объект может перемещаться с чрезмерной скоростью или не полностью или летать сквозь стены за пределы экрана. Даже если временной шаг постоянен, интеграция Эйлера вызывает незначительные ошибки в расчетах. Лучше использовать другой метод интеграции, такой как RK4, или использовать физический движок.

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

Стивен
источник