Я читаю Game Coding Complete, и автор рекомендует Event-Driven-коммуникацию между игровыми объектами и модулями.
По сути, все живые игровые актеры должны общаться с ключевыми модулями (физика, искусственный интеллект, игровая логика, игровой вид и т. Д.) Через внутреннюю систему обмена сообщениями о событиях. Это означает необходимость разработки эффективного менеджера событий. Плохо спроектированная система пожирает циклы процессора, особенно это касается мобильных платформ.
Это проверенный и рекомендуемый подход? Как я должен решить, использовать ли это?
architecture
software-engineering
events
Bunkai.Satori
источник
источник
libuv
недавно стала успешной библиотекой событий. (Это в C. Node.js - его самый известный вариант использования.)Ответы:
Это расширение моего комментария к полному ответу, как предложено.
Да , просто и понятно. Коммуникация должна происходить, и в то время как есть ситуации, когда «Мы уже там?» опрос типа требуется, чтобы вещи проверяли, должны ли они делать что-то еще, что обычно тратит время. Вместо этого вы могли бы заставить их реагировать на то, что им велено делать. Кроме того, четко определенный путь связи между объектами / системами / модулями значительно ускоряет параллельные установки.
Я дал общий обзор системы обмена сообщениями о событиях в Stack Overflow . Я использовал его из школы в профессиональных играх, а теперь и в неигровых продуктах, каждый раз, конечно, адаптируя их к конкретному случаю.
РЕДАКТИРОВАТЬ : Чтобы ответить на вопрос комментария о том, как вы знаете, какие объекты должны получить сообщение : сами объекты должны
Request
быть уведомлены о событиях. ВашEventMessagingSystem
(EMS) будет нуждаться вRegister(int iEventId, IEventMessagingSystem * pOjbect, (EMSCallback)fpMethodToUseForACallback)
сопоставленииUnregister
(создание уникальной записи дляiEventId
указателя объекта и обратного вызова). Таким образом, когда объект хочет узнать о сообщении, он может это сделатьRegister()
с системой. Когда ему больше не нужно знать о событиях, он можетUnregister()
, Очевидно, что вам нужен пул этих объектов регистрации обратного вызова и эффективный способ добавления / удаления их из списков. (Я обычно использовал самоупорядоченные массивы; причудливый способ сказать, что они отслеживают свои собственные распределения между стеком пула неиспользуемых объектов и массивами, которые смещают свои размеры при необходимости).РЕДАКТИРОВАТЬ : Для полностью работающей игры с циклом обновления и системой обмена сообщениями о событиях, вы можете проверить мой старый школьный проект . Связанный выше пост переполнения стека также относится к нему.
источник
Мое мнение таково, что вы должны просто начать создавать свою игру и реализовать то, что вам удобно. Когда вы сделаете это, вы обнаружите, что используете MVC в некоторых местах, но не в других; события одних мест, но не других; компоненты одних мест, но наследование других; чистый дизайн одних мест и грубый дизайн одних.
И это нормально, потому что, когда вы закончите, у вас действительно будет игра, и игра намного круче, чем система передачи сообщений.
источник
Лучший вопрос, какие есть альтернативы? В такой сложной системе с правильно разделенными модулями для физики, ИИ и т. Д. Как еще вы можете организовать эти системы?
Передача сообщений, кажется, является «лучшим» решением этой проблемы. Я не могу думать об альтернативах прямо сейчас. Но существует множество примеров передачи сообщений на практике. Фактически, операционные системы используют передачу сообщений для нескольких своих функций. Из Википедии :
(Межпроцессное взаимодействие - это взаимодействие между процессами (т.е. запущенными экземплярами программ) в среде операционной системы)
Так что, если он достаточно хорош для операционной системы, то, вероятно, достаточно хорош для игры, верно? Есть и другие преимущества, но я позволю статье объяснять в статье в Википедии о передаче сообщений .
Я также задал вопрос о переполнении стека: «Структуры данных для передачи сообщений в программе?» , который вы можете прочитать.
источник
Сообщения обычно работают хорошо, когда:
Чем больше ваши потребности соответствуют этому списку, тем лучше будут подходящие сообщения. На очень общем уровне они довольно хороши. Они делают хорошую работу, не тратя циклы ЦП просто для того, чтобы ничего не делать в отличие от опроса или других более глобальных решений. Они отлично подходят для отделения частей кодовой базы, что всегда полезно.
источник
Отличные ответы от Джеймса и Рикета, я отвечаю только, чтобы добавить предостережение. Передача сообщений / коммуникация, управляемая событиями, безусловно, является важным инструментом в арсенале разработчика, но его можно легко использовать слишком много. Когда у тебя молоток, все выглядит как гвоздь и так далее.
Вы абсолютно на 100% должны думать о потоке данных вокруг вашего заголовка и полностью осознавать, как информация передается из одной подсистемы в другую. В некоторых случаях передача сообщений явно лучше; в других может быть более целесообразно, чтобы одна подсистема работала над списком совместно используемых объектов, позволяя другим подсистемам также работать с тем же общим списком; и многие другие методы.
Вы всегда должны знать, каким подсистемам нужен доступ к каким данным и когда им нужен доступ к ним. Это влияет на вашу способность распараллеливать и оптимизировать, а также помогает вам избежать более коварных проблем, когда различные части вашего двигателя становятся слишком тесно переплетенными. Вам нужно подумать о минимизации ненужного копирования данных и о том, как макет данных влияет на использование кэша. Все это поможет вам найти лучшее решение в каждом конкретном случае.
При этом почти каждая игра, над которой я когда-либо работал, имела надежную систему асинхронной передачи сообщений / уведомлений о событиях. Он позволяет вам писать сжатый, эффективный и легко обслуживаемый код даже в условиях сложных и быстро меняющихся требований к дизайну.
источник
Ну, я знаю, что этот пост довольно старый, но я не удержался.
Я недавно построил игровой движок. Он использует сторонние библиотеки для рендеринга и физики, но я написал основную часть, которая определяет и обрабатывает сущности и игровую логику.
Двигатель, безусловно, следует традиционному подходу. Существует основной цикл обновления, который вызывает функцию обновления для всех объектов. О столкновениях напрямую сообщается обратным вызовом на объектах. Связь между объектами осуществляется с использованием интеллектуальных указателей, которыми обмениваются объекты.
Существует примитивная система сообщений, которая обрабатывает сообщения только небольшой группы объектов. Эти сообщения предпочтительно обрабатывать в конце игрового взаимодействия (например, создание или уничтожение сущности), поскольку они могут связываться со списком обновлений. Таким образом, в конце каждого игрового цикла используется небольшой список сообщений.
Несмотря на примитивную систему сообщений, я бы сказал, что система в значительной степени основана на цикле обновления.
Что ж. После использования этой системы, я думаю, что это очень просто, быстро и хорошо организовано. Логика игры является видимой и самодостаточной внутри сущностей, а не динамической, как сообщение quewe. Я действительно не хотел бы, чтобы это было обусловлено событиями, потому что, по моему мнению, системы событий вносят ненужную сложность в игровую логику и делают код игры очень сложным для понимания и отладки.
Но я также думаю, что у чистой системы, основанной на цикле обновления, как у меня, тоже есть некоторые проблемы.
Например, в некоторых моментах одна сущность может находиться в состоянии «ничего не делать», может ждать, когда игрок приближается, или что-то еще. В большинстве случаев сущность сжигает процессорное время впустую, и лучше выключить сущность и включить ее, когда происходит определенное событие.
Итак, в моем следующем игровом движке я собираюсь принять другой подход. Объекты будут регистрироваться для операций двигателя, таких как обновление, рисование, обнаружение столкновений и так далее. Каждое из этих событий будет иметь отдельные списки интерфейсов сущностей для реальных сущностей.
источник
Да. Это очень эффективный способ взаимодействия игровых систем друг с другом. События помогают вам разъединить многие системы и позволяют даже компилировать вещи отдельно, не зная о существовании друг друга. Это означает, что ваши классы могут быть легче прототипированы, а время компиляции быстрее. Что еще более важно, вы получите плоский дизайн кода вместо беспорядка зависимостей.
Другое большое преимущество событий заключается в том, что они легко передаются по сети или другому текстовому каналу. Вы можете записать их для последующего воспроизведения. Возможности безграничны.
Еще одно преимущество: у вас может быть несколько подсистем, прослушивающих одно и то же событие. Например, все ваши удаленные представления (игроки) могут автоматически подписаться на событие создания сущностей и порождать сущности на каждом клиенте, не занимая при этом много работы. Представьте, сколько еще работы было бы, если бы вы не использовали события: вам нужно было бы совершать
Update()
вызовы где-нибудь или, возможно, вызыватьview->CreateEntity
из логики игры (где знание о представлении и какая информация ему требуется, не принадлежит). Трудно решить эту проблему без событий.С событиями вы получаете элегантное и отделенное решение, которое поддерживает бесконечное количество объектов неограниченного типа, которые могут просто подписаться на события и делать свое дело, когда что-то происходит в вашей игре. Вот почему события великолепны.
Более подробная информация и реализация здесь .
источник
Из того, что я видел, кажется, что не очень часто иметь движок, полностью основанный на обмене сообщениями. Конечно, есть подсистемы, которые очень хорошо подходят для такой системы обмена сообщениями, как сеть, графический интерфейс и, возможно, другие. В общем, есть несколько проблем, о которых я могу подумать:
Таким образом, при использовании подхода общего разработчика игр «он должен быть максимально эффективным», такая система обмена сообщениями встречается не так часто.
Тем не менее, я согласен, что вы должны просто пойти дальше и попробовать. Такая система, безусловно, имеет множество преимуществ, и сегодня вычислительные мощности доступны дешево.
источник