Лучший подход к игровой анимации? - PullRequest
9 голосов
/ 08 марта 2009

У меня есть курсовое упражнение в OpenGL, чтобы написать игру с простой анимацией нескольких объектов

Обсуждая с моим партнером наши варианты дизайна, мы поняли, что у нас есть два основных варианта работы анимации: Либо

  • Установите таймер на постоянный интервал, скажем, 30 мсек, когда таймер сработает, рассчитайте, где должны быть объекты, и нарисуйте кадр. или -
  • Не используйте таймер, просто обычный цикл, который выполняется все время, и в каждой итерации проверяйте, сколько прошло времени, вычисляйте, где объекты должны быть в соответствии с интервалом, и рисуйте кадр.

Какой обычно должен быть предпочтительный подход? У кого-нибудь есть конкретный опыт использования любого из этих подходов?

Ответы [ 7 ]

10 голосов
/ 08 марта 2009

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

Не используйте таймер, они не надежны <50-100 мс в Windows. Проверьте, сколько времени прошло. (Обычно требуется и дельта, и абсолютное значение, в зависимости от того, основана ли ваша анимация на физике или на ключевом кадре.) </p>

Кроме того, если вы хотите быть стабильным, используйте верхнюю / нижнюю границу вашего временного шага, чтобы перейти в замедленное движение, если для рендеринга кадра требуется несколько секунд (доступ к диску другим процессом?) Или пропустите обновить, если вы получите два из них в течение, скажем, 10 мс.

Обновление (поскольку это довольно популярный ответ)

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

Update2 (Так как я получил 10 голосов;)

Для дальнейшей стабильности в течение длительных периодов работы (> 4 часов) вы, вероятно, захотите убедиться, что вы не используете float / double для вычисления больших временных различий, поскольку при этом вы теряете точность, и анимация / физика вашей игры будут страдать. Вместо этого используйте целые числа с фиксированной точкой (или 64-битные микросекунды).

Для волосатых деталей я рекомендую прочитать Вопрос точности Тома Форсайта.

4 голосов
/ 09 марта 2009

Читать эту страницу о игровых циклах.

Короче, установите таймер:

  • Обновление состояния игры на фиксированной частоте (примерно каждые 25 мс = 1 с / 40 к / с). Это включает в себя свойства игровых объектов, входные данные, физику, ИИ и т. Д. Я называю это Model и Controller . Необходимость фиксированной частоты обновления связана с проблемами, которые могут возникнуть на слишком медленном или слишком быстром оборудовании (читайте статью). Некоторые физические движки также предпочитают обновляться с фиксированной частотой.

  • Обновите фрейм (графику) игры как можно быстрее . Это было бы View . Таким образом, вы обеспечите плавную игру. Вы также можете включить vsync, чтобы дисплей ожидал графическую карту (обычно это 60 кадров в секунду).

Таким образом, на каждой итерации цикла вы проверяете, нужно ли обновлять модель / контроллер. Если уже поздно, обновляйте, пока они не будут обновлены. Затем обновите кадр один раз и продолжите цикл.

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

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

1 голос
/ 08 марта 2009

Вариант 2 гораздо предпочтительнее. Он будет хорошо масштабироваться на разной производительности оборудования.

В книге "Gems 1 Programming Gems 1" была глава, которая описывает именно то, что вам нужно:

Независимая от частоты кадров линейная интерполяция

1 голос
/ 08 марта 2009

Второй - мой предпочтительный подход, потому что таймеры часто не так точны, как вы, вероятно, думаете, и имеют все задержки и издержки системы обработки событий. Учет временного интервала придаст вашей анимации гораздо более согласованный вид и будет устойчивым, если / когда частота кадров снизится.

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

0 голосов
/ 08 марта 2009

Я бы предложил настроить систему на работу с «дельтой», которая передается извне.

Когда я сделал это, в формате анимации я все основывал на значениях в реальном времени. Дельта, через которую я прошел, составляла 1/30 секунды, но это могло быть что угодно. С помощью этой системы вы можете получить либо первый, либо второй вариант, в зависимости от того, передаете ли вы фиксированную дельту или количество времени, прошедшее с последнего кадра.

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

0 голосов
/ 08 марта 2009

Я бы соблазнился использовать цикл, поскольку он будет рендериться максимально быстро (т. Е. Сразу после того, как ваши физические вычисления будут сделаны). Это, вероятно, будет более надежным, если вы столкнетесь с каким-либо замедлением в вычислениях, что приведет к тому, что срабатывание таймера начнет стоять в очереди. Однако в случае такого замедления вам, возможно, придется ограничить временной интервал, вычисляемый между обновлениями, поскольку ваш физический движок может работать нестабильно при слишком большом скачке во времени.

0 голосов
/ 08 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...