Последние 48 часов я потратил на чтение компонентов систем компонентов и чувствую, что готов достаточно приступить к его реализации. Я создал базовые классы Object и Component, но теперь, когда мне нужно начать создавать настоящие компоненты, я немного запутался. Когда я думаю о них с точки зрения HealthComponent или чего-то, что в сущности будет просто собственностью, это имеет смысл. Когда это нечто более общее в качестве компонента физики / графики, я немного запутался.
Мой класс Object до сих пор выглядит следующим образом (Если вы заметили какие-либо изменения, которые я должен сделать, пожалуйста, дайте мне знать, все еще новичок в этом) ...
typedef unsigned int ID;
class GameObject
{
public:
GameObject(ID id, Ogre::String name = "");
~GameObject();
ID &getID();
Ogre::String &getName();
virtual void update() = 0;
// Component Functions
void addComponent(Component *component);
void removeComponent(Ogre::String familyName);
template<typename T>
T* getComponent(Ogre::String familyName)
{
return dynamic_cast<T*>(m_components[familyName]);
}
protected:
// Properties
ID m_ID;
Ogre::String m_Name;
float m_flVelocity;
Ogre::Vector3 m_vecPosition;
// Components
std::map<std::string,Component*> m_components;
std::map<std::string,Component*>::iterator m_componentItr;
};
Теперь проблема, с которой я сталкиваюсь, состоит в том, что население в целом поместит в такие компоненты, как физика / графика? Для Ogre (мой движок рендеринга) видимые объекты будут состоять из нескольких Ogre :: SceneNode (возможно, нескольких), чтобы прикрепить его к сцене, Ogre :: Entity (возможно, нескольких), чтобы показать видимые сетки, и так далее. Будет ли лучше просто добавить несколько объектов GraphicComponent к объекту и позволить каждому объекту GraphicComponent обрабатывать один SceneNode / Entity, или вам нужна идея иметь один из каждого компонента?
Для физики я еще больше запутался. Я полагаю, возможно, создание RigidBody и отслеживание массы / interia / и т.д. будет иметь смысл. Но мне трудно думать о том, как на самом деле поместить специфику в компонент.
Как только я сделаю пару этих «Обязательных» компонентов, я думаю, это будет иметь больше смысла. На данный момент, хотя я все еще немного озадачен.
источник
Компонентная архитектура является альтернативой, позволяющей избежать больших иерархий, которые достигаются при наследовании всех элементов от одного узла, и проблем связывания, которые ведут.
Вы показываете компонентную архитектуру с «общими» компонентами. У вас есть базовая логика для подключения и отсоединения «общих» компонентов. Архитектуру с общими компонентами сложнее достичь, потому что вы не знаете, какой это компонент. Преимущества в том, что этот подход расширяемый.
Действительная архитектура компонентов достигается с помощью определенных компонентов. С определенным я имею в виду интерфейс, а не реализация. Например, GameObject может иметь IPhysicInstance, Transformation, IMesh, IAnimationController. Преимущество этого в том, что вы знаете интерфейс, а GameObject знает, как обращаться с каждым компонентом.
Отвечая на термин сверхобобщающий
Я думаю, что понятия не ясны. Когда я говорю «компонент», это не значит, что все компоненты игрового объекта должны наследоваться от интерфейса компонента или чего-то подобного. Однако это подход к универсальным компонентам, я думаю, что это концепция, которую вы называете компонентом.
Компонентная архитектура является еще одной из архитектур, существующих для объектной модели времени выполнения. Это не единственный и не лучший вариант для всех случаев, но опыт показал, что он имеет много преимуществ, таких как низкая связь.
Главной особенностью, которая отличает архитектуру компонентов, является преобразование отношения is-a в has-a. Например, объектная архитектура is-a:
Вместо объектной архитектуры есть -a (компоненты):
Существует также имущественно-ориентированная архитектура:
Например, нормальная объектная архитектура выглядит так:
Object1
Object2
Имущественно-ориентированная архитектура:
Позиция
ориентация
Лучше объектная модель архитектуры? С точки зрения производительности, он лучше ориентирован на свойства, потому что он более кеш-ориентирован.
Компонент ссылается на отношение is-a вместо has-a. Компонентом может быть матрица преобразования, кватернион и т. Д. Но отношение с игровым объектом является отношением a-a, у игрового объекта нет преобразования, поскольку оно наследуется. Игровой объект имеет (отношение имеет-а) преобразование. Преобразование тогда является компонентом.
Игровой объект похож на хаб. если вам нужен компонент, который всегда есть, то, возможно, компонент (например, матрица) должен быть внутри объекта, а не указатель.
Существует не идеальный игровой объект для всех случаев, это зависит от движка, библиотек, которые использует движок. Может быть, я хочу камеру, которая не имеет сетки. Проблема с архитектурой заключается в том, что если у игрового объекта есть сетка, то у камеры, которая наследуется от игрового объекта, должна быть сетка. Благодаря компонентам у камеры есть трансформация, контроллер движения и все, что вам нужно.
Для получения дополнительной информации глава 14.2. Архитектура объектной модели времени выполнения из книги «Архитектура игрового движка» Джейсона Грегори посвящена именно этому вопросу.
UML-диаграммы извлекаются оттуда
источник