2D矢量,重叠&数组中不同类型的对象

时间:2013-03-23 23:06:33

标签: c++ class vector multidimensional-array

我目前正在思考如何为某种游戏板制作2D矢量数组。

棋盘应该是向量,因为大小可以变化,每个“正方形”应该包含有关该方块中的对象的信息。

问题是可能存在重叠的对象,并且对象可能不是同一类型或类。

这就是我目前正在考虑的事项:(伪代码)

struct Square {
    vector<enum type>;
    vector<pointers to objects>;
};

vector< vector <Square> >;

指针指向不同的矢量数组,每个数组都保存特定的对象。

我不确定如何制作这样的功能,或者如果这是可能的,我认真考虑这可能会更复杂,然后需要...

有些对象必须是类,但是我可以在游戏板类中创建从一个主类继承的所有类型的对象。但最后对象是完全不同的所以我不确定这是否有多少差异。

我是否只是盲目而且错过了一种更简单的方法来做我正在尝试做的事情:2D数组包含不同类型的元素,这些元素也可以在数组中重叠?

我非常感谢任何帮助,片段或洞察力。

注意: 创建后,棋盘大小不会有机会。 物体必须能够在棋盘中移动。

1 个答案:

答案 0 :(得分:1)

这是我的建议。

#include <boost/shared_ptr.hpp>

class GameObject {
  public:
    virtual ~GameObject() {}

    enum Type {
       FOO,
       BAR
    };
    virtual Type type() const = 0;

    virtual std::string name() const = 0;
    virtual void damaged() {}
};

class FooObject : public GameObject {
  public:
     Type type() const { return FOO; }

     std::string name() const { return "Foo object"; }
     void damaged() {
        std::cout << "Foo was damaged!" << std::endl;
     }
};

class BarObject : public GameObject {
  public:
     Type type() const { return BAR; }

     std::string name() const { return "Bar object"; }
     // Bar object doesn't respond to damage: no need to override damaged()
};

class Square {
   std::vector<boost::shared_ptr<GameObject> > objects;
};

class Board {
   // Details of the implementation here not important, but there
   // should be a class to hide them.

   Square* squares;
   int width, height;

   Board(int width, int height) :
     squares ( new Square[ width * height ] ),
     width ( width ),
     height ( height )
   {
   }

   ~Board() {
      delete [] squares;
    }

   Square& square(int x, int y) {
      if( x < 0 || x >= width || y < 0 || y >= height ) {
          throw std::logic_error( "accessed square out of bounds" );
      }
      return squares[ x + width * y ];
   }
};

要点:

  • 为可放置在游戏板上的各种对象设置一个基类。
  • 此类的类必须具有虚拟析构函数,即使它是微不足道的。这是因为您将通过GameObject指针删除内容。
  • 如果需要区分游戏对象,请使用返回“类型”值的虚拟方法。
  • 只要使用它,就不要使用该类型值,而是使用其他有意义的虚拟方法。使用类型值(然后通常转换为子类型)应该被视为最后的手段。例如(自由发明有关游戏的细节):
    • 每个对象都有一个名称,显示何时将光标放在它上面。这是以name()返回的。
    • 游戏中的事件可能会对对象造成“伤害”。这仅适用于某些类型的对象,因此对damaged()的默认操作是什么都不做。 Foo对象响应损坏,通过实际操作覆盖它。
  • 但是你实现了这个板,在一个类中隐藏你的确切实现。 (不要把我的代码作为你不应该使用vector&lt;&gt;的指示,这绝对没问题。我对这里的矢量&lt; vector&lt;&gt;&gt;有轻微的个人偏好,但这也不算太糟糕。)
  • 使用游戏对象的共享指针。
    • Boost有一个很好的,广泛使用的实现。
    • 如果您不能使用共享指针,请控制Square类之外的游戏对象的生命周期(例如,在Board类中所有游戏对象的主列表中),然后使用Square类中的原始指针。
    • 如果您确实使用了共享指针,并且这是您第一次使用,请先简要阅读它们。它们不是魔术,你需要注意某些事情,比如循环引用。
  • 根据您的需要,您可能希望GameObject中的“反向链接”包含方块或方块的坐标,其中包含指向该GameObject的指针。这样您就可以轻松地从电路板上移除物体并移动它们。