2013-03-23 68 views
1

我目前正在思考如何去做一个游戏板的2D矢量阵列。二维矢量,重叠和阵列中的不同类型的对象

董事会应该是向量,因为大小可以变化,每个“方块”应该包含关于该方块中的对象的信息。

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

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

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

vector< vector <Square> >; 

和指针的会指向不同的向量阵列各持特定对象。

我不确定如何使这样的功能,或者如果这甚至有可能和我认真想这可能是更复杂然后它需要..

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

我是否正在失明并且失去了一个更简单的方法来做我想做的事情:二维数组持有不同类型的元素,也可以在数组中重叠?

我真的很感谢任何帮助,片段或见解。

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

+0

游戏板的大小可以在游戏板创建后改变,或者您的意思是说您需要不同尺寸的板? – svk 2013-03-23 23:14:40

+0

不,创建后,棋盘大小不会有机会。 – xardex 2013-03-24 00:37:55

回答

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指针来删除东西。
  • 如果有必要区分游戏对象,请使用返回“类型”值的虚拟方法。
  • 只要使用而不是,不要使用该类型的值,而是使用其他虚拟方法来代替有意义的事情。使用类型值(然后通常转换为子类型)应该被认为是最后的手段。例如(自由发明游戏细节):
    • 每个对象都有一个名称,当您将光标放在它上面时,会显示一个名称。这是以名称()返回的。
    • 游戏中的事件可能会导致对象“损坏”。这只适用于某些对象,所以对于()的默认操作是什么都不做。 Foo对象对伤害作出反应,用实际行动覆盖它。
  • 但是,如果您实施董事会,请将您的具体实施隐藏在班级中。 (不要拿我的代码作为表明你不应该使用矢量<>,这绝对没问题。我有一个轻微的个人喜好对付矢量<这个,但这也不算太坏。
    • Boost有一个伟大的和广泛使用的实现。
    • 如果您不能使用共享指针,请在Square类之外控制游戏对象的生命周期(例如,在Board类中所有游戏对象的主列表中),然后在Square类中使用原始指针。
    • 如果您确实使用共享指针,并且这是您第一次执行操作,请首先简要阅读它们。他们不是魔术,你需要小心某些事情,例如循环引用。
  • 根据您的需要,您可能希望GameObject中的“反向链接”包含指向该GameObject指针的正方形或正方形坐标。这将允许您轻松地从电路板上移除物体并移动它们。
+0

谢谢,我想我会像这样做我的对象类。但我不确定董事会的建议。我没有真正提到它,但物体在地图中移动。我会如何将一个物体从一个方块移动到另一个方块?如果我将一个正方形的指针从另一个正方形中删除,然后再添加到另一个正方形中,该对象是不会被删除的 这些笔记更新了第一篇文章。 – xardex 2013-03-24 12:51:05

+0

(我假设你的意思是在这里使用智能指针,否则你几乎完全控制/负责删除。)当你从Square中删除一个对象时,你可以从Square矢量中创建一个本地智能指针。然后将其从矢量中移除,但该对象不会被删除,因为您仍然有本地智能指针。然后,您可以将其插入另一个Square的向量中,然后让本地智能指针超出范围。我认为,如果你试图写出代码,你会发现你不需要做任何特别的事情 - 这是做这件事的自然方式。 – svk 2013-03-24 12:57:31

+0

有趣。非常感谢,我想我可以从这里拿走它。 – xardex 2013-03-24 17:22:34