2016-03-11 164 views
0

我正在製作FireEmblem風格的遊戲,目前我正在處理項目。我有一個Weapon類,其中Sword,Axe等等。我也有像Swordsman,Mage等人物類。我想有一種方法讓班級只裝備某些武器(Swordsman可以裝備Sword而不是Axe)。我想到的一種方法是獲得全局枚舉WeaponType,並且每個武器都有一個const值weapon_type。然後,每個角色類別都有一個允許列表WeaponTypes,你會檢查武器的weapon_type是否在允許列表中。允許一個單位只裝備某些類型的武器

有沒有更好的實現方法?

+0

這可能更適合於GameDesign.SE – NathanOliver

+1

@NathanOliver不一定,拋開遊戲,這是一個如何在相應的類層次結構之間進行耦合的問題。 –

+0

嘗試從關係角度來處理問題,而不是面向對象的問題。這個問題很難解決;你會有一個「武器」表,一個「字符」表和一個「weapon_permission」表,外鍵引用另外兩個表。 –

回答

0

認爲你有你的角色的基類的功能,看起來像

class CharacterBase { 
public: 
     bool equip(Weapon* weapon) { 
      if(checkWeaponType(weapon)) { 
       weapons.push_back(weapon); 
       return true; 
      } 
      return false; 
     } 
protected: 
     virtual bool checkWeaponType(Weapon* weapon) const = 0; 
private: 
     std::vector<Weapon*> weapons; 
}; 

你能提供實際檢查,如果Weapon指針傳遞具有正確類型的實現

class SwordsMan : public CharacterBase { 
protected: 
     virtual bool checkWeaponType(Weapon* weapon) const { 
      return dynamic_cast<Sword*>(weapon) != nullptr; 
     } 
}; 

也讓我們假設你的SwordsMan字符也被允許穿Dagger,那麼你擴展你的支票,如

 virtual bool checkWeaponType(Weapon* weapon) const { 
      return dynamic_cast<Sword*>(weapon) != nullptr || 
        dynamic_cast<Dagger*>(weapon) != nullptr ; 
     } 
+0

這是我的另一個想法,但我想知道是否有一個不需要鑄造的有效方法 – Chara

+0

@Chara你也可以使用靜態多態(引入模板),但對於這種情況'dynamic_cast'似乎更多在相應的班級中靈活轉向。 –

+0

我明白了,這種方式比創建允許的武器類型的字符串數組/枚舉數組方便得多。謝謝 – Chara

0

只是產卵。

假設你允許的武器是你類中的一個字符串數組(string weaponAllow [10])。

而你的武器有名字。 爲你的法師/戰士類製作一個對象陣列(生病叫它戰士)。 也許當你有你的裝備功能,或當你裝備你說:

for(int a=0; a<=10; a++) { 
    if(soldier[whichTypeOfSoldier].weaponAllow[a]==item[whichitem].name) { 
     (code to equip the item) 
    } 
} 

我想當然地認爲你已經使用對象數組,如果沒有,我建議使用它們。

嗯,我只是產卵。希望你明白我的意思。

0

考慮以下幾點:

struct WeaponAttributes { 
    // Attributes to designate damage and weaknesses to 
    // specific character classes and armor types. 
}; 

class Weapon { 
public: 
    enum WeaponClassType { 
     WCT_SWORD, 
     WCT_AXE, 
     WCT_DAGGER, 
     WCT_KNIFE, 
     WCT_STAFF, 
     /* WTC_ETC */ 
    }; 
private: 
    std::string m_strWeaponClass; 
    std::string m_strWeaponName; 

    WeaponClassType m_WeaponClass; 

public: 
    // Constructor, Destructor and members this base class would have 
    Weapon(const std::string& strWeaponClass, const std::string& strWeaponName, WeaponClassType weaponType); 

    std::string getWeaponClassName() const; 
    std::string getWeaponName() const; 

    WeaponClassType getType() const; 

    bool isWeaponType(const WeaponClassType& type) const; 
    bool isWeaponType(const std::string& strClassName) const; 

    void addAttributes(const WeaponAttributes& attributes) = 0;   
}; 

class Sword : public Weapon { 
private: 
    WeaponAttributes m_attributes; 

public: 
    explicit Weapon(const std::string& strWeaponName); 

    void addAttributes(const WeaponAttributes& attributes) override; 

}; 

struct CharacterAttributes { 
    // Similar to WeaponAttributes 
}; 

class Character { 
public: 
    enum CharacterClassType { 
     CCT_FIGHTER, 
     CCT_WARRIOR, 
     CCT_MAGE, 
     /* CCT_ETC */ 
    }; 

private: 
    std::string m_strCharacterClassType; 
    std::string m_strCharacterClassName; 
    std::string m_strPlayerOrNPCName; 

    CharacterClassType m_classType; 

public: 
    Character(const std::string& strName, const std::string& strClassName, const std::string strClassType, CharacterClassType classType); 

    // Using Three Strings - Example: (Player's or NPC's game name, White, Mage) 
    // (Player's or NPC's game name, Superior, Warrior) 
    // (Player's or NPC's game name, Skilled, Fighter) 
    std::string getName() const; 
    std::string getClassName() const; 
    std::string getCharacterName() const; 

    CharacterClassType getCharacterType() const; 

    bool isCharacterClassType(const CharacterClassType& type) const; 
    bool isCharacterClassType(const std::string& strClassType) const; 

    void addCharacterAttributes(const CharacterAtrributes& attributes) = 0; 
    bool equipWeapon(Weapon* pWeapon) = 0; 
    bool equipArmor(Armor* pArmor) = 0; 
}; 

class Character : public Fighter { 
private: 
    CharacterAttributes m_attributes; 

    std::shared_ptr<Weapon> m_pWeapon; 
    std::shared_ptr<Armor> m_pArmor; 

public: 
    Fighter(const std::string& strPlayerOrNPCName, const std::string& strClassName); 

    void addCharacterAttributes(const CharacterAttributes& attributes); 
    bool equipWeapon(Weapon* pWeapon); 
    bool equipArmor(Armor* pArmor); 
}; 

對於這種類型的類層次,每個類都有一個枚舉類型和字符串描述符與方法來檢索類型,字符串和比較,如果他們是特定類型或不一起,您可以輕鬆遍歷不同的列表或向量(容器),以查看是否可以將特定類型的裝甲或武器裝備到特定的職業角色。這只是一種設計方法,因爲有很多方法來實現這樣的系統。我並不誇耀這是最好或最差的設計方法,但我覺得它是一個很好的指導或起點。一旦你在沒有任何錯誤的情況下得到你想要的工作穩定狀態所需的行爲,那麼只有這樣纔可以修改現有代碼庫進行優化。