[英]Data structure 2d/3d array of tiles C++
我正在為新游戲編寫關卡編輯器。 問題是,我不確定用於存儲數據的結構。
它是基於圖塊的地圖引擎,在該位置使用x和y坐標以及圖塊的ID。
我有多層,地圖是可調整大小的,所以數組可能會給我帶來一些麻煩,這就是為什么我為這種情況選擇std :: vector的原因。 為避免大量的過載,我只在有人放置時添加了一個圖塊,因此如果沒有圖塊,則向量大小為零,並且增加的圖塊數將增加。
struct tile {
unsigned short tile_id;
unsigned short tile_x;
unsigned short tile_y;
};
而我的載體:
std::vector<tile> tiles;
關鍵是,在添加新的圖塊之前,我需要檢查在x和y位置是否已經有圖塊。
// Returns true/false if there is a tile at given position or not
bool Layer::has_tile_at(unsigned short x, unsigned short y) {
unsigned int i;
for (i = 0; i < tiles.size(); i++) {
if (tiles[i].tile_x == x && tiles[i].tile_y == y)
return true;
}
return false;
}
我的問題是,對於每個放置的瓷磚,我都必須遍歷整個矢量,該矢量在一開始就很快速,但是在放置了某些瓷磚之后,確實讓屁股有些痛苦。
您認為到目前為止我的方法還可以,還是有一些更聰明,更高效的方法?
要使用的數據結構應主要取決於用例:如果您主要進行(x,y)讀取,則可能需要一個矩陣(通過向量的向量或僅通過數組的數組)。
如果您需要索引訪問並且需要在圖塊上輕松迭代,則可以將數據保留在兩個數據結構中。 您應該能夠輕松實現帶有指向矢量內圖塊的指針的2d映射-最初是空的,在(x,y)訪問時被延遲加載(請記住有關數據安全性!)。
考慮例如:
class Map
{
public:
void addTile(std::shared_ptr<Tile> tile)
{
m_tiles.push_back(tile); // should probably remove old elements at (x,y) from the vector
m_map[{tile->x, tile->y}] = tile; // overwrites whatever was stored in there!
}
std::shared_ptr<Tile> getTile(int x, int y)
{
return m_tilesMap[{x, y}]; // if no tile there, returns default ctor-ed shared_ptr: nullptr
}
private:
std::vector<std::shared_ptr<Tile>> m_tiles;
using Index2D = std::pair<int, int>;
std::map<Index2D, std::shared_ptr<Tile>> m_tilesMap;
};
(帶有簡短代碼示例的擴展注釋:數據保留在堆上,而向量和映射都保留其副本-也許可以進行改進以方便刪除)
為什么不使用多個向量? 您實際上可以通過具有向量的向量來創建可增長的二維向量,然后重載[]運算符以首先檢查向量的大小是否可以包含該元素(如果不是則返回false),如果可以,則檢查該元素不是一個構造值(無論您的默認“ tile”是什么)。 這將允許像常規向量一樣進行近O(1)查找。 否則,您可以使用公式計算最大的col / row距離,並通過2-D到1-D轉換(例如在2-D數組中)進行O(1)查找。
這就是我的想法:
vector< vector<tile> > tiles;
bool::Layer has_tile_at(unsigned short x, unsigned short y) {
if (tiles.size() <= x) {
return false;
} else if (tiles[x].size() > y) {
if (tiles[x][y] != tile()) {
return true;
}
}
return false;
}
編輯:
正如另一個用戶指出的那樣,您還可以使用指針並檢查tile [x] [y] == nullptr; 代替!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.