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

2D vector, overlapping & different types of objects in array

本文关键字:同类型 对象 重叠 2D 数组 矢量      更新时间:2023-10-16

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

棋盘应该是矢量,因为大小可以变化,每个"方块"应该包含关于该方块中对象的信息。

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

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

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

指针指向不同的vector数组,每个数组都包含特定的对象。

我不确定如何使这样的功能,或者如果这是可能的,我认真地认为这可能更复杂,然后它需要…

有些对象必须是类,但我可以让所有类型的对象在游戏棋盘类继承一个主类。但最终,对象是完全不同的,所以我不确定这是否有很大的不同。

我只是盲目,错过了一个更简单的方法来做我想做的事情:2D数组持有不同类型的元素,也可以在数组中重叠?

我非常感谢任何帮助,片段或见解。

指出:创建后,板大小不会改变。对象必须能够在面板上移动

我的建议是:

#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指针删除内容。
  • 如果有必要区分游戏对象,使用返回"type"值的虚拟方法。
  • 只要不是必须使用它,就不要使用该类型值,而是使用其他做有意义的事情的虚拟方法。使用类型值(然后通常将其转换为子类型)应该被视为最后的手段。例如(自由地创造游戏细节):
    • 每个对象都有一个名称,当你把光标放在它上面时显示出来。这在name()中返回。
    • 游戏中的事件可能会对物体造成"伤害"。这只适用于某些类型的对象,因此damage()的默认操作是什么都不做。foo对象对伤害做出反应,用实际的动作覆盖它。
  • 无论你如何实现电路板,将你的确切实现隐藏在类中。(不要把我的代码当作不应该使用vector<>的指示,这绝对没问题。我个人对vector<>>在这里,但这也不是太糟糕。)
  • 为游戏对象使用共享指针。
    • Boost有一个很好的和广泛使用的实现。
    • 如果你不能使用共享指针,那就在Square类之外控制游戏对象的生命周期(例如,在Board类中所有游戏对象的主列表中),然后在Square类中使用原始指针。
    • 如果您确实使用共享指针,并且这是您第一次使用,请先简要阅读它们。它们不是魔法,你需要注意某些事情,比如循环引用。
  • 根据你的需要,你可能想要在GameObject中有一个指向正方形的"反向链接",或者正方形的坐标,包含指向GameObject的指针。这将允许您轻松地从板上删除对象并移动它们。