我有一个类怪物,当一个实例被创建时,它应该将每个怪物与武器联系起来。恩。狮鹫怪物应该有狮鹫攻击1和狮鹫攻击2,当然攻击的名字是TBD,但是现在好用狮鹫攻击1和2.
Currenly我有这个。
#include <vector>
typedef enum {Living, Dead, Nature} Race;
typedef enum {Gryphon, Oracle, Mercenary,Templar,
Satyr,Fallin Angel,ArcAngel,Satan,Grimreaper,
Unbaptized Babies,Boggart,Succubus,Meat Wagon,
Djinns,Manticore,Water Nymph,Plant Nymph,
Mother Nature, Cannibal Tribesmen,Wyvern,
Vegetable Lamb, Ent, Lava Worm, Alpha Dragon
} MonsterType;
typedef enum {gryphon1,Oracle1, Mercenary1,Templar1,
Satyr1,Fallin Angel1,ArcAngel1,Satan1,Grimreaper1,
Unbaptized Babies1,Boggart1,Succubus1,Meat Wagon1,
Djinns1,Manticore1,Water Nymph1,Plant Nymph1,
Mother Nature1, Cannibal Tribesmen1,Wyvern1,
Vegetable Lamb1, Ent1, Lava Worm1,Alpha Dragon1,
Gryphon2, Oracle2, Mercenary2,Templar2,
Satyr2,Fallin Angel2,ArcAngel2,Satan2,Grimreaper2,
Unbaptized Babies2,Boggart2,Succubus2,Meat Wagon2,
Djinns2,Manticore2,Water Nymph2,Plant Nymph2,
Mother Nature2, Cannibal Tribesmen2,Wyvern2,
Vegetable Lamb2, Ent2, Lava Worm2, Alpha Dragon2
} Weapon;
Class Monsters{
protected:
MonsterType type;
Race race;
std::vector<Weapon> weapon_list;
public:
bool flying;
bool lava;
bool water;
int life;
int karmaCost;
int move;
int crit;
int defMagic;
int defNonMagic;
bool isDead;
bool canMove;
bool canAttack;
bool onFlag;
int nextTurn;
};
我不确定这个矢量,也不是它需要它只是我正在搞乱的一些实验..但是什么是将武器与怪物联系起来的最佳方法?还要注意每个武器都有与之相伴的值,所以
gryphon attack 1 {
int range = 10
int ticks = 5
bool magical = false
int power = 23
bool heals = false
}
gryphon attack 2 {
int range = 5
int ticks = 7
bool magical = true
int power = 29
bool heals = true
}
从ini或网络读入实际值,所以不担心实际值,但我需要知道我可以添加值gryphon->weapon1->range = 5
我仍然很新,所以如果出现问题,请告诉我。
答案 0 :(得分:4)
根据经验说明:您选择的方法将来会导致许多问题。我知道我并没有完全回答你的问题,但我这样做只是为了省你一些麻烦。如果你想按照自己的方式去做,请原谅我和/或无视这一点。
不要为每个怪物或角色创建专门的类。创建一个单一的,抽象的复合类,其中包含许多描述该游戏对象各个方面的属性。有点像:
// simplified class declaration, not a C++ code
class GameActor {
ActorVisualization visualization;
vector<InventoryItems> inventory;
ActorStatistics stats;
vector<ActorEffects> appliedEffects;
}
此类抽象对象将用于游戏中的所有Actors
,包括玩家角色。
下一步是将访问者模式用于此actor可能发生的所有事情。
// continued
class GameActor {
bool applies(Visitor& visitor);
void accept(Visitor& visitor) {
if (applies(visitor)) {
visitor.visit(this);
}
}
}
class Visitor {
void visit(GameActor& actor);
}
根据需要扩展您的GameActor
以满足您的需求。无论何时添加新功能,请尝试使用已实现的访问者机制。仅在必要时创建GameActor
的新属性。
访客样本?它可以用不同的方式编写,但我希望它能说明事情应该如何完成。
class DamageInflictedVisitor {
int amount;
damageType_t dmgType;
void visit(GameActor& actor) {
double res = actor.getStats().getResistances().getResistanceForType(dmgType);
int finalAmount = amount * (1-res);
actor.getStats().inflictDamage(finalAmount);
}
}
class ActorAliveVisitor {
void visit(GameActor& actor) {
if (actor.getStats().hp <= 0) {
if (actor.getType() == AT_MONSTER) {
// remove from the game, create a new ExperienceGained visitor applicable for players, etc.
} else if (actor.getType() == AT_PLAYER) {
// notify the game that the given player is dead
}
}
}
}
通过使用此类简单访问者,您可以获得非常好的代码可读性,只需查看其名称即可了解每个访问者的行为。
答案 1 :(得分:1)
尝试为怪物制作层次结构,而不是大型列表。 例如基类怪物,它只有位置/方向和种族。然后你创建一个派生类LivingMonster,例如它有健康,还有一个具有武器的LivingArmedMonster类。 这将确保你不会得到一个臃肿的类,并使以后更容易添加使用其他功能的怪物,而不会炸毁大怪物类。
至于你的武器:列表是一个好主意,我唯一想补充的就是使用指针,从那以后你就可以拥有不同的武器(来自基类:武器),而无需更改列表。 它还可以让你更容易在怪物之间交换武器(你拥有一个可以制造所有武器的武器存储)然后你可以放下并拿起武器,所以你只需将指针从1个怪物的武器向量移动到另一个。 这比复制整个对象的强度要小[/ p>]
答案 2 :(得分:1)
Class Weapon {
int range;
int ticks;
bool magical;
int power;
bool heals;
public Weapon(int range, ......){
this->range = range;
...
}
};
Class Monster{
protected:
MonsterType type;
Race race;
std::vector<Weapon> weapon_list;
public:
int life;
int karmaCost;
...
void addWeapon(Weapon w){
weapon_list.push_back(w);
}
};
Class FlyingMonster : public Monster{
public:
int flightSpeed;
}
Class MonsterFactory{
static FlyingMonster *CreateGryphon(){
FlyingMonster *gryphon = new FlyingMonster();
gryphon.addWeapon(WeaponFactory::CreateGryphonAttack1());
gryphon.addWeapon(WeaponFactory::CreateGryphonAttack2());
return gryphon;
}
};
Class WeaponFactory{
static Weapon* CreateGryphonAttack1(){
Weapon* w = new Weapon(gryphonAttack1BaseRange);
return w;
}
};
FlyingMonster* tom = MonsterFactory::CreateGryphon();
tom->weapon_list[0].range = 50;