Entity System в C++
Я недавно обнаружил архитектуру EntitySystem, и у меня есть некоторые трудности, чтобы сделать это в C++ / понять реализацию.
Как я вижу Entity System:
Компоненты: класс с атрибутами, набором и получением.
- эльф
- Physicbody
- SpaceShip
- ...
Система: класс со списком компонентов.
- Элемент списка
- EntityManager
- Renderer
- вход
- камера
- ...
Entity: просто пустой класс со списком компонентов.
Что я сделал:
В настоящее время у меня есть программа, которая позволяет мне сделать это:
// Create a new entity/
Entity* entity = game.createEntity();
// Add some components.
entity->addComponent( new TransformableComponent() )
->setPosition( 15, 50 )
->setRotation( 90 )
->addComponent( new PhysicComponent() )
->setMass( 70 )
->addComponent( new SpriteComponent() )
->setTexture( "name.png" )
->addToSystem( new RendererSystem() );
Если я правильно понял EntitySystem, каждая система имеет свой собственный список компонентов, с которыми она работает. (Список компонентов или список сущностей, это вопрос)
class Component;
/////////////////////////////////////////////////
/// \brief An abstract system. (Interface)
///
/////////////////////////////////////////////////
class System
{
public:
/////////////////////////////////////////////////
/// \brief Call when process is created.
///
/////////////////////////////////////////////////
virtual bool start() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is updated.
///
/////////////////////////////////////////////////
virtual void update() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void end() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void addComponent( Component* component )
{
elements.push_back( component );
}
protected:
std::vector<Component*> elements;
};
(Я поместил код в.h просто для быстрой отладки ^^)
Эта проблема
Я хочу добавить компонент "T" в систему со списком компонентов X
Что я пробовал:
std::vector<Component*> elements;
Но я хочу что-то подобное:
std::vector<T*> elements;
Мой Системный класс абстрактный. У моего класса System детский класс должен иметь этот список с собственным типом.
Решение:
Я пытался поставить мой класс System имеет шаблонный класс, поэтому я просто должен сделать: class Renderer: System
Но мой SystemManager не нравится этот код: std::vector<System> systems
,
Системный класс с типом T:
template<class T>
class System
{
public:
/////////////////////////////////////////////////
/// \brief Call when process is created.
///
/////////////////////////////////////////////////
virtual bool start() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is updated.
///
/////////////////////////////////////////////////
virtual void update() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void end() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void addComponent( T* component )
{
elements.push_back( component );
}
protected:
std::vector<T*> elements;
};
Код SystemManager:
class System;
class SystemManager
{
public:
/////////////////////////////////////////////////
/// \brief Default constructor.
///
/////////////////////////////////////////////////
SystemManager();
/////////////////////////////////////////////////
/// \brief Call when system is created.
/// \param system A system to add.
///
/////////////////////////////////////////////////
bool addSystem( System* system);
/////////////////////////////////////////////////
/// \brief Call when system is updated.
///
/////////////////////////////////////////////////
void update();
/////////////////////////////////////////////////
/// \brief Call when system is removed.
/// \param system A system to remove.
///
/////////////////////////////////////////////////
void removeSystem( System* system );
private:
std::vector<System*> systemList;
};
При этом в SystemManager появилась ошибка:"Переопределение" System "как символа другого типа"(указание на строку "class System" в SystemManager).
У вас было решение этой проблемы? Мой Entity System подходит хорошо?
Спасибо!
1 ответ
В вашем коде System - это шаблон, позже в классе System manager вы пытаетесь использовать System, как если бы это был не шаблон. Это не будет работать. Вам нужно либо указать тип, сделать системный менеджер шаблоном и передать параметр типа в систему, либо система не будет шаблоном. Кроме того, объявление шаблонов, как не шаблонов, не сработает. Сделайте шаг назад и выясните, как работают шаблоны в C++.
Более того, на http://gamedev.stackexchange.com/ есть много вопросов и ответов о дизайне компонентов сущностей, которые могут оказаться полезными.