矢量数据链接

Vector data linking

本文关键字:链接 数据      更新时间:2023-10-16

我有一个怪物类,当创建一个实例时,它应该将每个怪物与武器联系起来。鹰头怪应该有鹰头狮攻击1和鹰头狮攻击2,当然攻击的名称是待定的,但现在我们使用鹰头狮攻击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

我还是很新的,所以如果有什么事情似乎很错误,请告诉我。

根据经验:你选择的方法将来会导致很多问题。我知道我并没有确切地回答你的问题,但我这样做只是为了给你省去一些麻烦。如果你想按你的方式去做,请原谅我和/或忽略下面的内容。

不要为每个怪物或角色创建专门的职业。创建一个抽象的复合类,其中包含描述游戏对象各个方面的属性。就像这样:

// simplified class declaration, not a C++ code
class GameActor {
  ActorVisualization visualization;
  vector<InventoryItems> inventory;
  ActorStatistics stats;
  vector<ActorEffects> appliedEffects;
}

这样的抽象对象将用于你游戏中的所有Actors,包括玩家角色。

下一步是使用访问者模式来处理这个参与者可能发生的所有事情。

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

通过使用这样的简单的访问者,你有很好的代码可读性,你知道每个访问者做什么仅仅通过看它的名字。

尝试为你的怪物创建一个层次结构,而不是一个大的类型列表。例如,只有位置/方向和种族的基类Monster。然后你创建一个派生类LivingMonster,它添加了生命值,还有一个类LivingArmedMonster拥有武器。这将确保你不会得到一个臃肿的类,并使以后添加使用其他函数的怪物更容易,而不会破坏大怪物类。

至于你的武器:列表是一个好主意,我唯一要添加的是也许使用一个指针,因为你可以有不同的武器(从基类派生:武器),而不改变列表。同时这也让怪物间的武器交换变得更容易(游戏邦注:你拥有一个能够创造所有武器的武器存储库),然后你便可以放下并捡起武器,所以你只需要将指针从一个怪物的武器向量移动到另一个怪物身上。这比复制整个对象要简单得多

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;