Я только начал работать над системой компонентов сущностей для игры в sidescroller.
Я довольно новичок в C ++, но я уже прочитал много учебников и решил, что лучшим способом будет иметь класс сущности, который содержит вектор компонентов. Тогда будет базовый класс компонентов с собственно компонентами как подклассы.
Entity.h:
#ifndef _ENTITY_H
#define _ENTITY_H
#include "header.h"
class Entity
{
public:
Entity();
~Entity();
// Vector which stores all added components
vector<Component*> Components;
// Add component method
void AddComponent(Component* component);
};
#endif
Entity.cpp:
#include "header.h"#include "Component.h"#include "Entity.h"
Entity::Entity(){}
Entity::~Entity(){}
void Entity::AddComponent(Component* component)
{
Components.push_back(component);
}
Component.h:
#ifndef _COMPONENT_H
#define _COMPONENT_H
#include "header.h"
class Component
{
public:
// Forward declaration
class Entity;
Component();
~Component();
void Connect(Entity* entity) {}
string Name;
};// Position component
class Position: public Component{
public:
int x, y;
};
// Display component
class Display: public Component{
public:
sf::Sprite baseSprite; };
#endif
Component.cpp:
#include "header.h"#include "Component.h"
Component::Component(){}
Component::~Component(){}
Теперь, чтобы добавить новый компонент, я бы сделал что-то вроде этого:
Entity* new_component;
new_component = new Entity;
new_component->AddComponent(new Position);
new_component->AddComponent(new Display);
Проблема в том, что я не знаю, как на самом деле снова получить доступ к компоненту после его добавления.
Я хотел бы иметь доступ, например, к значениям x и y позиции. Но когда я пытаюсь получить доступ к компонентам в списке, как это:
Components[i]->...
Я только придумаю атрибуты базового компонента класса.
Любая помощь приветствуется.
Вы можете хранить определенные типы компонентов в определенном индексе.
Например, все компоненты положения хранятся в положении 0, все компоненты скорости сохраняются в положении 1.
Тогда вы можете легко получить компоненты
template <class T>
T * Entity::getComponent()
{
return static_cast<T*>(components[T::getIndex()]);
}
Component :: getIndex () — это статический метод, который должен возвращать индекс для этого компонента.
использование static_cast<T>
или же dynamic_cast<T>
приведение элемента вектора к соответствующему типу перед доступом к методам производного класса.
Использовать static_cast<T>
вы должны будете помнить, какой элемент какого типа, потому что static_cast<T>
не скажу вам.
dynamic_cast<T>
вернет нулевой указатель, если T
не имеет соответствующего типа указателя, но это влечет за собой некоторые накладные расходы времени выполнения (что меня не слишком беспокоит).
В качестве примечания я бы серьезно подумал о редизайне, чтобы не было необходимости в кастинге.