6

我有一个怪物类,当创建一个实例时,它应该将每个怪物与那里的武器联系起来。前任。狮鹫怪物应该有狮鹫攻击 1 和狮鹫攻击 2,当然攻击的名称是 TBD,但现在还是使用狮鹫攻击 1 和 2。

目前我有这个。

    #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

我对此仍然很陌生,所以如果看起来很不对,请告诉我。

4

3 回答 3

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
      }
    }
  }
}

通过使用这样简单的访问者,您具有非常好的代码可读性,您只需查看每个访问者的名称就知道它在做什么。

于 2013-06-12T07:43:08.180 回答
1

尝试为你的怪物创建一个层次结构,而不是一个大的类型列表。例如只有位置/方向和种族的基类怪物。然后你创建一个派生类 LivingMonster,它添加了例如健康,以及一个类 LivingArmedMonster,它有武器。这将确保您不会得到一个臃肿的类,并且可以更容易地在以后添加使用其他功能的怪物而不会炸毁大怪物类。

至于你的武器:这个列表是个好主意,我唯一要补充的可能是使用一个指针,因为这样你就可以拥有不同的武器(从基类派生:武器)而无需更改列表。它还可以更容易地在怪物之间交换武器(你有一个创建所有武器的武器存储)然后你可以放下和拿起武器,所以你只需将指针从一个怪物的武器矢量移动到另一个。这比复制整个对象的强度要小得多

于 2013-06-10T09:30:28.117 回答
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;
于 2013-06-12T07:45:03.993 回答