为我的2d C ++游戏实现组件系统

时间:2017-08-11 02:59:20

标签: c++ components game-engine

我一直在试图找到一种方法来实现我的简单2d格斗游戏的组件系统,我可以轻松地交换从我的系统函数返回的新组件。我的想法是我有一堆系统函数可以处理一组组件:

示例:

PosisiontComponent MovementSystem(PositionComponent pos, VelocityComponent vel)
{
    //..Make entity move
   return pos;
}

这里的关键是我想返回组件的新副本,而不是直接在我的系统函数中修改状态(为了更容易理解和测试系统)。理想情况下,这个新的更新位置组件然后可以通过某种类型的myFighter.Insert()成员函数插入到我的Fighter中(其作用基本上类似于实体类)。到目前为止,我正在考虑使用std::map<int key, Component* comp>来存储我的组件,其中键是一个唯一的id,它只与一种组件类型连接,我可以使用它来查找映射中的某些组件。战斗机类可能看起来像:

class Fighter
{
public:
    void Insert(Component* comp);
    Component* Get();

    std::map<int, Component*> componentMap;
}

Fighter::Fighter(std::string const imageFilePath, float startPositionX, float startPositionY) :
    sprite(imageFilePath, 200, 200)
{
    componentMap[0] = new PositionComponent(glm::vec2{ 0.0f, 0.0f });
    componentMap[1] = new VelocityComponent();
}

void Fighter::Insert(Component* component)
{
    componentMap.erase(compID);
    componentMap[compID)] = component;
}

Component* GetComponent()
{
   return componentMap[id];
}

我遇到的问题是我不知道如何通过GetComponent()函数返回单个组件(当前只是由于类型问题的转换而导致编译器错误)与当前实现。

我的问题是:

1。)我目前的实施是否可行?有没有办法从GetComponent()函数中提取特定组件而不会遇到编译器问题?如果没有,最好的方法是轻松换掉我的Fighter类中的各个组件吗?

1 个答案:

答案 0 :(得分:0)

假设每个实体每个类型只能有一个组件,您可以使用模板。

template<typename T>
T* getComponent() {
    for (auto &component : components)
    {
        T* derivedComponent = dynamic_cast<T*>(component);
        if (derivedComponent)
        {
            return derivedComponent;
        }
    }

    return NULL;
}

然后使用它将很简单,并且不需要共享id。此外,可以在不破坏游戏的情况下更改地图的顺序。当您在运行时添加和删除组件时会发生这种情况。

Fighter* f;
PosisiontComponent* positionComponent = f->getComponent<PosisiontComponent>();

这是我过去使用的方法,它运作得非常好。但是,我建议使用智能指针而不是这些容器的原始指针。