C ++有效地存储Tile Map切片

时间:2014-10-16 06:41:43

标签: c++ sfml

我正在制作一个基于TileMap的游戏引擎。

我有一个“Tile”类,它用于定义块类型和设置标志以确定属性(isSolid,isEmitter)。现在我有一个2d的平铺对象数组[MAP_WIDTH] [MAP_HEIGHT]。

现在我知道不需要为游戏中的每个实际图块存储新图块,但我需要找到一种以更简单的格式存储地图数据的方法。我最初的想法是存储无符号整数的二维数组(或向量),但我无法将其作为可扩展的解决方案。

如何用数字表示每个Tile?因此,在渲染函数中,我可以说“从存储在数组中的整数值渲染图块的类型”E.G. renderTileType(地图[X] [Y])

对不起,这是我的第一个问题,请原谅我的任何罪过。

提前致谢!

4 个答案:

答案 0 :(得分:3)

只需将所有独特的瓷砖存储在一个不需要更改的矢量中,除非在程序启动期间。然后像这样制作一个2D数组:

Tile* map[MAP_WIDTH][MAP_HEIGHT]

然后您可以简单地在此2D数组中指定指针以指向vector<Tile>中的相应Tile。 Tiles的生命周期当然会由向量管理,因此您不需要newdelete任何内容。

答案 1 :(得分:2)

您可以使用的是flyweight模式的实现。

所以你有一个二维瓷砖阵列。

Tile map[MAP_WIDTH][MAP_HEIGHT];

但是,磁贴包含有关本地信息的信息以及指向共享信息的指针。

class Tile {
   // Stuff that is really shared between all tiles of the same type.
   TileImpl * impl;

   // Other stuff that varies with location in the map.
   // maybe you want to store items there, or flags, or procedures.
   ItemInfo * items;
   Flags    * flags;
   Procedures* procs;
}

// This is the stuff that all tiles of this type share.
class TileImpl {
  string imageFile;
  bool hurtsMeIfIStandOnIt;
  bool isPassable;
}

答案 2 :(得分:0)

当我在游戏服务器设置中执行此操作时,我使用了2D指针数组,并且大多数指针都指向共享Tiles(在我的情况下是Room *),而我的Room有一个共享vs的标记独特。我能够进行懒惰的实例化,如果玩家在沙漠中游荡,我会在访问每个房间时根据需要实例化共享沙漠房间的独特副本。房间有数据结构,如播放器/对象列表,因此任何有内容的房间也可能是预先实例化的。但99%的地图指向共享的房间,这使得堆使用效率更高。

Tile / Room也有一个低基数枚举类型,或者一个简单的短字节或短整数,它是基于零的索引到另一个Tile类型数组,它包含颜色,位图,规则等详细信息。

如果数组大小成为问题,只需将阵列分解为象限系统,并根据需要进行加载/卸载。

答案 3 :(得分:0)

这里需要一个特定的数据结构,它将整数ID与实际的Tile对象进行映射。 如果您可以访问C ++ 11(更好的查找复杂性),则可以使用名为std::map的类,或std::unordered_map

只需声明整数的数组(一维或二维,无论如何),在加载时填充它,当需要使用实际Tile(碰撞检测,绘图等)执行操作时,只需从地图上得到它。

示例:

std::unordered_map<std::uint16_t, Tile *> tileMap;
tileMap[0] = /* get tile object for ID 0 */;
tileMap[1] = /* get tile object for ID 1 */;
…

Tile *currentTile = tileMap[idMap[x][y]]; // Here you get the tile from the ID at (x, y)

另一个解决方案是使用InternalTile类,它拥有每个昂贵的资源(纹理...),并将指针或引用传递给正在构造的每个Tile对象的适当实例。但由于每个Tile不使用唯一属性,因此它不太有用。