2017-08-11 39 views
0

我一直在想辦法爲我的簡單2d格鬥遊戲實現一個組件系統,在這裏我可以輕鬆地交換從我的系統函數返回的新組件。這個想法是我有一堆的系統功能,這將在一組部件的工作:爲我的2d C++遊戲實現組件系統

例如:

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返回單個組件(功能(目前剛剛起步,由於轉換編譯器錯誤類型問題)與當前的實現。

我的問題(S)是:

1)是我目前的執行可行的解決方案?有沒有辦法從GetComponent()函數中提取特定的組件而不會發生編譯器問題?如果沒有,最好的方法是更換我的Fighter類中的單個組件。

回答

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>(); 

這是我過去使用的方法,它的工作原理非常好。但是,我會建議使用智能指針而不是這些容器的原始指針。

+0

感謝您的建議!但是,讓我問你,鑑於getcomp調用的頻率,dynamic_cast效果的性能呢? – Jason

+0

@Jason是的,它的確,動態演員陣容很多,但速度很快。它會影響性能。 – skypjack