Зарегистрировать компоненты игровых объектов в игровых подсистемах?(Компонентный дизайн игровых объектов) - PullRequest
7 голосов
/ 18 октября 2010

Я создаю систему объектных игровых объектов .Несколько советов:

  1. GameObject - это просто список Components.
  2. . Есть GameSubsystems.Например, рендеринг, физика и т. Д. Каждый GameSubsystem содержит указатели на некоторые из Components.GameSubsystem - это очень мощная и гибкая абстракция: она представляет любой фрагмент (или аспект) игрового мира.

Необходим механизм регистрации Components в GameSubsystems (когда GameObject создан и составлен).Есть 4 подхода :


  • 1: Цепочка ответственности шаблон.Каждое Component предлагается каждому GameSubsystem.GameSubsystem принимает решение, какую Components зарегистрировать (и как их организовать).Например, GameSubsystemRender может зарегистрировать Renderable Components.

pro.Components ничего не знают о том, как они используются.Низкая связь. A. Мы можем добавить новые GameSubsystem.Например, давайте добавим GameSubsystemTitles, который регистрирует все ComponentTitle и гарантирует, что каждый заголовок уникален и предоставляет интерфейс для запроса объектов по заголовку.Конечно, ComponentTitle не должен быть переписан или унаследован в этом случае. B. Мы можем реорганизовать существующие GameSubsystems.Например, GameSubsystemAudio, GameSubsystemRender, GameSubsystemParticleEmmiter можно объединить с GameSubsystemSpatial (чтобы поместить все аудио, emmiter, рендер Components в одну иерархию и использовать родительские относительные преобразования).

con.Индивидуальная проверка.Очень неэффективно.

con.Subsystems знать о Components.


  • 2: Каждый Subsystem ищет Components определенных типов.

pro.Лучшая производительность, чем у Approach 1.

con.Subsystems все еще знает о Components.


  • 3: Component регистрируется в GameSubsystem(s).Мы знаем во время компиляции, что существует GameSubsystemRenderer, поэтому давайте ComponentImageRender вызовет что-то вроде GameSubsystemRenderer :: register (ComponentRenderBase *).
    Observer pattern.Component подписывается на событие "update" (отправлено GameSubsystem(s)).

pro.Спектакль.Нет ненужных проверок, как в Approach 1 и Approach 2.

con.Components плохо связаны с GameSubsystems.


  • 4: Mediator pattern.GameState (содержит GameSubsystems) может реализовывать registerComponent (Component *).

pro.Components и GameSubystems ничего не знают друг о друге.

con.В C ++ это выглядело бы как уродливый и медленный переключатель типа.


Вопросы: Какой подход лучше и в основном используется в компонентном проектировании?О чем говорит практика?Любые предложения по (управляемой данными) реализации Approach 4?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 18 октября 2010

Голосуйте за третий подход.

В настоящее время я работаю над компонентной системой игровых объектов и ясно вижу некоторые дополнительные преимущества этого подхода:

  • Компонент - все более самодостаточная субстанция, поскольку он зависит только от набора доступных подсистем (я предполагаю, что этот набор зафиксирован в вашем проекте).

  • Проект на основе данных более применим. В идеале таким способом вы можете разработать систему, в которой компоненты полностью определены в терминах данных, но не в C ++.


РЕДАКТИРОВАТЬ: Одна функция, о которой я думал, работая над CBGOS. Иногда удобно иметь возможность проектировать и конструировать пассивные компоненты без подсистемы . Когда вы думаете об этом, четвертый подход - единственный путь.

1 голос
/ 26 июня 2014

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

Таким образом, если требуется удалить объект из механизма, в каждую подсистему может быть отправлено одно сообщение, содержащее идентификатор объекта. Затем прокси-сервер можно удалить из каждой коллекции подсистем независимо.

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