2016-03-11 88 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); 
}; 

对于这种类型的类层次,每个类都有一个枚举类型和字符串描述符与方法来检索类型,字符串和比较,如果他们是特定类型或不一起,您可以轻松遍历不同的列表或向量(容器),以查看是否可以将特定类型的装甲或武器装备到特定的职业角色。这只是一种设计方法,因为有很多方法来实现这样的系统。我并不夸耀这是最好或最差的设计方法,但我觉得它是一个很好的指导或起点。一旦你在没有任何错误的情况下得到你想要的工作稳定状态所需的行为,那么只有这样才可以修改现有代码库进行优化。