Загрузка...
 
Печать
ИГРОКОДИНГ  »  ИГРОКОДИНГ: Учебный курс  »  Программируем 3D-шутер от первого лица (FPS) (Win32, Cpp, DirectX9)  »  Часть 1. Создание движка  »  Формы и методы управления игровым движком

Формы и методы управления игровым движком


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

Когда ты справшиваешь кого-либо о том, что собой представляет игровой движок, то часто можно слышать в ответ "3D-рендеринг" или "3D-графика". В принципе, они правы, т.к. большинство современных движков, так или иначе, используются для обработки 3D-рендеринга в играх. В то же время, термин "управление игровым движком" следует воспринимать в более широком смысле. Помимо 3D-рендеринга, игровой движок должен также "организовать" создание игры. Важно всё время помнить об этом, разрабатывая движок. И планировать его так, чтобы в нём было всё необходимое для создания FPS-игры.
Среди разработчиков-любителей распространена ошибка, когда они забывают внедрить систему управления движком ещё на ранних стадиях его разработки. Вместо этого, они доводят до ума возможности 3D-рендеринга движка ещё до того, как попытались контролировать его.
Прежде чем отправится дальше, давай определим понятие "управление игровым движком" (Engine control). Точнее, определим, из чего же складывается этот самый контроль движка. Для этой цели мы разделим понятие "управление игровым движком" на 2 отдельных (но взаимосвязанных) аспекта:

  • Процессинг движка (Engine processing)
  • Пользовательский ввод (User input)
Рис.1 Главный цикл игрового приложения (Game loop)
Рис.1 Главный цикл игрового приложения (Game loop)

Процессинг движка (Engine processing)

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

Например, большинство движков работают с использованием так называемого игрового цикла (Game loop; см. Рис. 1). На Рис. 1 изображена упрощённая схема и часть пунктов здесь просто не представлено, но присутствуют основные компоненты. Игровой цикл - это просто продолжающийся цикл, который выполняется снова и снова до тех пор, пока не будет прерван (обычно это происходит при выходе пользователя из игры и закрытии приложения). Часто такие циклы выполняют более 30 проходов (= итераций) за секунду, что определяется фреймрейтом (framerate, частота смены кадров(external link)) игры или по-другому - числом кадров в секунду (frames per second; отсюда аббревиатура fps).
Если твой игровой цикл работает на скорости 40 fps, тогда теоретически каждый кадр занимает 2,5% от одной секунды, что соответсвует 25 милисекундам (мс) на кадр. Другими словами, игровой цикл совершает одно полное прохождение каждые 25 мс. Любой нормальный движок проделывает уйму работы за это время (см. Рис.1). Вот здесь-то контроль процессинга движка и выходит на первый план. Раз уж у нас в каждом кадре столь ограничено время, то необходимо расходовать его с умом. По сути, весь контроль процессинга нашего движка сводится к управлению этими 25 милисекундами и определению, какой отрезок времени будет выделен каждому компоненту.
Допустим, пользовательский ввод, сеть, звук и рендеринг вместе взятые занимают 18 мс. В таом случае у нас остаётся всего 7 мс для процессинга, специфичного для приложения (application-specific processing). Взять хотя бы игровую логику, которая также может содержать времязатратные операции, например систему искусственного интеллекта. Мы, конечно, проникли в эту тему несколько глубже, чем следовало бы для данной статьи. В любом случае, тебе важно помнить об этом, например для того, чтобы ты понимал некоторые девелоперские решения, которые мы реализуем позднее. Вот лишь некотореы из них:

  • Ограничение числа итераций детекции столкновений (collision detection);
  • Прекращение процессинга сетевых сообщений (network message processing) по истечении определённого времени;
  • Ограничение размера нашй иерархии сцены (scene hierarhy).

На даном этапе мы уже имеем более чёткое представление о контроле процессинга движка. Исходя из вышеизложенного материала, мы создадим систему, которая сможет указывать, как компоненты из Рис.1 будут работать вместе чтобы обработать один аспект симуляции, более известный как стейт (англ. "state" - состояние). Эту систему часто называют машина конечных состояний (Finite-State Machine, далее - FSM(external link)) или т.н. "конечный автомат". Этот абстрактный термин широко используется во многих отраслях программирования. Более подробно мы расскажем о нём позднее, когда речь пойдёт о том, как мы сможем его использовать для целей контроля процессинга движка.

Пользовательский ввод (User input)

  • Также является формой контроля движка, так как позволяет пользователю контролировать в некоторой степени работу движка и в гораздо большей степени - работу игры, созданной на основе этого движка.

И ответственнен за это именно движок. Мы внедрим пользовательский ввод в наш движок, используя готовые интерфейсы DirectInput (рассмотрим позднее).

Машины конечных сосотяний (Finite-State Machines)

Мы будем использовать простую форму FSM для управления различными стейтами, которые нашему движку может понадобиться обработать в опеределённый момент времени. Прежде чем мы применим эту хитрую концепцию к нашему случаю, кратко обсудим FSM. На самом деле это очень простая концепция, если разбить её название на отдельные слова и рассмотреть каждое из них по отдельности.
Первым идёт слово finite (англ. "конечный, ограниченый"), который чаще всего означает ограниченый. В терминах FSM это звучит как имеющий определённое число стейтов. Вообще, теоретически вполне возможно, но на практике практически невозможно существование неограниченного числа стейтов. Мы можем заключить, что все машины состояний ограничены и имеют ограниченное число стейтов, зависящее от того, сколько их назначил программер. Очень скоро мы рассмотрим наглядный пример.
Второе слово state (англ. "стейт, состояние"). В программировании стейт - это текущая диспозиция (состояние) и поведение данного события (entity) в данный момент времени. Например, ты можешь вызвать стейт, в котором ты сейчас находишься (т.е. стейт чтения). Когда ты идёшь на прогулку, ты можешь назвать это стейтом прогулки (walking state). Позднее ты сядешь за стол, чтобы перекусить. Всё это действо ты также можешь назвать стейтом приёма пищи (eating state). Ещё более простым примером может служить обычный выключатель на стене, который имеет всего 2 стейта: вкл и выкл. В данный момент времени выключатель может находится только в одном из двух стейтов.
Третье слово machine (англ. "машина"), которое просто может быть определено как система. Ведь, елси подумать, любая машина - это ни что иное как система. Она получает ввод от пользователя (оператора), обрабатывает его и выдаёт результат. Взять, к примеру, двигатель автомобиля. Это машина, которую также можно назвать системой, так как он получает ввод (топливо), обрабатывает его (сжигает) и выдаёт результат (энергию).
Если быть более точным, наша FSM это на самом деле динамическая машина, так как она может изменять способы своей обработки, что, в свою очередь, связано со способностью сменять стейты. В то время как двигатель автомобиля во время своей работы имеет всего 1 стейт (т.к. в данный мометн времени он принимает только 1 вид ввода (топливо), обрабатывает его и выдаёт единственный вид результата (энергию)), то наша FSM в этом плане больше похожа на слайд-проектор. В то время, как сам слайд-проектор остаётся неизменным, его ввод (слайды), процессинг (в какой-то степени) и выводимый результат могут изменяться. Ты можешь сменить слайд (ввод), что приведёт к изменению поведения света, проходящего через слайд (процессинг) и даст различные изображения, спроектированные на экране (вывод).

Рис.2 Упрощённая FSM гипотетического животного
Рис.2 Упрощённая FSM гипотетического животного

Таким образом можно заключить, что FSM - это система, которая может динамически изменять свои ввод, процессинг и вывод, основываясь на ограниченном наборе предопределённых стейтов (состояний).
Рис.2 показывает упрощённую FSM гипотетического животного. У животного есть своя внутренняя FSM, которая может сменять стейты на любой из представленных. Вместе с тем, в данный момент времени активным может быть только один стейт. При установке определённого стейта животное ведёт себя соответственно этому стейту. В этом примере нас интересуют всего 2 вопроса:

  • Как FSM сменяет стейты?
  • Как мы можем это использовать в нашем движке?

Ответы, на удивление, очень просты. Любая FSM сменяет свои стейты двумя способами: автоматически и в ручном режиме.
При автоматическом режиме FSM сменяет стейты через направление, указанное в текущем стейте. В нашем примере (из Рис.2) в стейте "охотиться" может содержаться инструкция, которая информирует FSM об автоматическом переходе на стейт "есть" всякий раз, когда животное поймает свою добычу.
При ручном режиме пользователь вмешивается в работу FSM и выбирает желаемый стейт. Возвращаясь к нашему примеру с животным, после того как оно преследовало добычу какое-то время, хищник очень устал и принуждает свою FSM сменить стейт на "спать".
Остаётся последний вопрос: как мы можем использовать это в нашем движке? Мы создадим систему, которая позволит игрокодеру (пользователю движка) определять для игры один или несколько стейтов. Затем система будет проверять, что движок обрабатывает нужный стейт в нужное время, параллельно предоставляя игрокодеру возможность переключаться между этими стейтами по мере необходимости. Это обезопасит нас от ситуации, когда движок затрачивает ценное время на процессинг фичей, которые в данный момент времени даже не используются.


1. Vaughan Young. "Programming a multiplayer FPS in DirectX", Charles River Media, Inc. 2005. Перевод с англ.: Артем Томашкевич

ИГРОКОДИНГ  »  ИГРОКОДИНГ: Учебный курс  »  Программируем 3D-шутер от первого лица (FPS) (Win32, Cpp, DirectX9)  »  Часть 1. Создание движка  »  Формы и методы управления игровым движком

Contributors to this page: slymentat .
Последнее изменение страницы Пятница 27 / Май, 2016 16:30:49 MSK автор slymentat.

Последние комментарии

No records to display

Хостинг