我面临以下设计问题:
TL; TD需要确定Hero(类)是否可以使用特定对象,而有许多英雄实现
我有3个Hero类的子类,每个子类都可以使用特定的项目。
对于Weapons.hpp,我有Sword,Hammer,CrossBow,Bow,Wand,Staff。
战士可以使用剑或锤子 弓箭手可以使用CrossBow或弓箭 向导可以使用工作人员或魔杖
有Hero基础课:
class Hero: public Entity{
public:
Hero(std::string name, Gender gender, double damage, Point2d* location);
~Hero();
virtual void move(int x, int y);
virtual void damage(Entity* other); // Override
virtual bool use(Potion* _potion);
virtual bool use(Weapon* _weapon) = 0;
virtual bool use(ShieldArmor* _shieldArmor) = 0;
virtual bool use(BodyArmor* _bodyArmor) = 0;
private:
std::string name;
Gender gender;
Weapon* weapon;
ShieldArmor* shield_armor;
BodyArmor* body_armor;
};
这是武器:
class Weapon: public Item{
public:
Weapon(double damage, Point2d* location);
virtual ~Weapon();
virtual double getDamage() const;
virtual const Point2d* getLocation() const;
virtual const std::string toString() const;
private:
Point2d* location;
double damage;
};
在游戏主游戏中,我需要确定Hero * h是否可以使用特定项目,如果可能的话,不使用向下投射。
所以我可以像以下一样使用它:
Hero *h;
Weapon * i;
// do something assign values
h->use(i);
答案 0 :(得分:2)
我通过删除所有不必要的内容并将其概括为Item
的概念来简化示例。武器是物品的子类,药水,魔杖,助焊剂电容器等等。 use
方法执行Item
对target
所做的任何操作。武器将试图击中并伤害target
。治疗药水会愈合target
。磁通电容器将及时发送target
或者以1.21千兆瓦的速度消除其中的咒骂。
但是通过Item
的镜头可以看到一切。调用类不知道项目是什么,做什么,或者对target
做了什么。 target
甚至不知道它上面使用了什么,它们只是感受到了效果。没有人知道关于简单通用界面之外的其他对象。
class Item
{
public:
enum types
{
whole lot of types go here.
They are fairly broad categories, like knife, sword, two handed sword,
healing potion, wand, etc.
};
types getType()
{
return type;
}
virtual bool use(Entity * target) = 0;
private:
types type;
};
class Hero: public Entity{
public:
Hero(std::set<Item::type> & usable): usableItems(usable)
~Hero();
bool use(Item* item,
Entity * target)
{
// this is the magic. If the item's type is in the list of usable items,
// the item is used on the target. They exact type of item or target
// is not known. Polymorphism will take care of everything from here
if (usableItems.find(item->getType()) != usableItems.end())
{
return item->use(target);
}
return false;
}
private:
std::set<Item::type> & usableItems;
};
关键是主要类是非常愚蠢的。它们只是为更详细的对象提供框架来完成详细的工作。 VorpalSword
使用从Weapon
和Item
继承的通用方法来查看它是否点击target
,而不知道target
实际上是HugeRedDragon
个实例,如果它击中指定伤害,然后执行VorpalSword
检查截肢的特定事情。
所有Hero看到的都是item->use(target)
。
答案 1 :(得分:0)
您可以使用dynamic_cast<>()
来确定Hero指针的类型,如下所示:
Hero *h;
Weapon * i;
// do something assign values
if(dynamic_cast<HeroSubClass> != nullptr)
h->use(i);
其中HeroSubClass
是您要检查的Hero
的特定子类(Warrior
等)。如果Hero *
不是指向类HeroSubClass
对象的指针,dynamic_cast
将返回nullptr
,如果是,则返回HeroSubClass *
。< / p>
或者,你可以检查每个HeroSubClass中Weapon *
内use()
的类型,也许打印出类似&#34; Warrior不能使用Staff&#34;如果它是错误类的对象。
答案 2 :(得分:0)
您可以使用enum
值来定义武器和英雄的特定类型。
enum class HERO_TYPE{
WARRIOR,
ARCHER,
WIZARD
}
class Hero: public Entity{
public:
Hero( std::string name, Gender gender, double damage, Point2d* location, HERO_TYPE type );
~Hero();
virtual void move(int x, int y);
virtual void damage(Entity* other); // Override
virtual bool use(Potion* _potion);
virtual bool use(Weapon* _weapon) = 0;
virtual bool use(ShieldArmor* _shieldArmor) = 0;
virtual bool use(BodyArmor* _bodyArmor) = 0;
private:
std::string name;
Gender gender;
Weapon* weapon;
ShieldArmor* shield_armor;
BodyArmor* body_armor;
HERO_TYPE type; //define in subclasses.
};
并为武器做同样的事。
enum class WEAPON_TYPE{
SWORD,
CROSSBOW,
WAND
}
class Weapon: public Item{
public:
Weapon(double damage, Point2d* location, WEAPON_TYPE type);
virtual ~Weapon();
virtual double getDamage() const;
virtual const Point2d* getLocation() const;
virtual const std::string toString() const;
WEAPON_TYPE get_type() { return this->type; }//getter
private:
Point2d* location;
double damage;
WEAPON_TYPE type;
};
现在你可以为英雄类指定武器了。
void Hero::use(Weapon *i){
if(!checkWeapon(i->get_type())) return;
//...code...
}
bool Hero::checkWeapon(WEAPON_TYPE t){
switch(this->type){
case HERO_TYPE::WARRIOR:{
if(t == WEAPON_TYPE::SWORD)
return true;
}break;
case HERO_TYPE::ARCHER:{
if(t == WEAPON_TYPE::CROSSBOW)
return true;
}break;
//..all cases..
}
return false;//no hero-weapon matching
}
答案 3 :(得分:0)
我正考虑使用访客模式。
类似的东西:
Hero * h;
Item * i;
Visitor v;
// Assign some values
h.accept(v,i);
然后访客看起来像:
visit(sword *p, warrior * w){
w.use(p);
}
visit(wand *p, wizard * w){
w.use(p);
}
visit(bow *p, archer * w){
w.use(p);
}
有关这个想法的任何建议吗?