Некоторое время назад я начал создавать игры и наткнулся на стиль, который мне действительно нравится. Это называется компонентной архитектурой. Учебник предназначен для Objective-C, а не C ++, но я все равно включил ссылку:
http://www.raywenderlich.com/24878/introduction-to-component-based-architecture-in-games
Я заметил, что копирую и вставляю много кода из проекта в проект, поэтому я решил просто создать библиотеку для общей платформы. Обычно компоненты включаются в объект сущности, например:
#ifndef ENTITY_H
#define ENTITY_H
#include "HealthComponent.h"#include "MoveComponent.h"#include "PlayerComponent.h"#include "RenderComponent.h"
class Entity
{
public:
Entity();
HealthComponent* getHealth();
//Returns a reference to the object's health component
//If there is none, returns a null pointer
MoveComponent* getMove();
//Returns a reference to the object's movement component
//If there is none, returns a null pointer
PlayerComponent* getPlayer();
//Returns a reference to the object's player component
//If there is none, returns a null pointer
RenderComponent* getRender();
//Returns a reference to the object's render component
//If there is none, returns a null pointer
~Entity();
private:
HealthComponent* health;
MoveComponent* move;
PlayerComponent* player;
RenderComponent* render;
};
#endif //ENTITY_H
Поскольку моя библиотека будет содержать общие рамки, а не отдельные компоненты, этот метод больше не работает. Вместо этого я создал ComponentManager
класс для управления моими компонентами. В настоящее время сущность выглядит так:
#ifndef ENTITY_H
#define ENTITY_H
#include "Component.h"#include "ComponentManager.h"#include <list>
class Entity
{
public:
Entity();
Entity(ComponentManager const & cmanager);
template <T>
T* getComponent();
//Returns the first component of the specified type
//If there is none, returns NULL
template <T>
T* getComponent(int i);
//Returns the ith component of the specified type
//If the component does not exist, returns NULL
template<T>
int getComponentCount();
//Returns the number of components of the specific type that the
//entity contains
template <T>
int addComponent(T &component);
//Adds a component of the specified type to the class. If a component of the
//class already exists, the component is assigned a number, and the number is returned.
//If no components of the class exist, 0 is returned
~Entity();
private:
int eid;
std::list<ComponentReference> components;
ComponentManager * manager;
};
#endif //ENTITY
Я еще не определил эти функции, поэтому я не включил файл имплиментации.
ComponentReference
struct просто представляет собой набор целых и строк, используемых для определения местоположения конкретного компонента. Сущность будет передавать ComponentReference
к шаблонной функции в manager
, который будет искать его внутренний список для конкретного объекта. И есть кирпичная стена. Я не знаю, как бы я создал список, содержащий неизвестное количество объектов разных неизвестных типов. Они получены от родителей Component
класс, но все они содержат разные функции и переменные-члены. Я пытался использовать массив указателей и приведение типов, но через три часа я сдался, когда прочитал, что чрезмерная зависимость от приведения типов является показателем плохо написанного кода.
Я пытался использовать контейнеры STL, но им нужен только один тип, так что, очевидно, они не будут работать
(C ++ std :: vector с указателями на шаблонный класс)
Я видел кое-что о оболочках, но из того, что я прочитал, они работают только с функциями 🙁c ++ хранит указатель на функцию-член неизвестного класса) Если они могут быть использованы для решения моей проблемы, пожалуйста, объясните, как они работают (я никогда не слышал о них до сегодняшнего дня)
Так как это мой первый вопрос, не стесняйтесь оставлять отзывы. Я провел исследование, но если это дубликат, извините. Я не новичок в C ++, но я также не эксперт, и это большой язык, поэтому я могу попросить разъяснений. Заранее спасибо!
Задача ещё не решена.
Других решений пока нет …