2013-03-23 53 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