我正在学习Cocos2dx,而且我正在使用平铺地图。 所以,让我们考虑以下代码:
auto map = TMXTiledMap::create("map.tmx");
auto layer = map->getLayer("Tile Layer 1");
auto gid = layer->tileGIDAt(Point(X, Y));
最后一行对我很重要。我很困惑,因为我看到了tileGIDAt(Point)的实现:
uint32_t TMXLayer::getTileGIDAt(const Vec2& pos, TMXTileFlags* flags/* = nullptr*/)
{
CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
ssize_t idx = static_cast<int>((pos.x + pos.y * _layerSize.width));
// Bits on the far end of the 32-bit global tile ID are used for tile flags
uint32_t tile = _tiles[idx];
// issue1264, flipped tiles can be changed dynamically
if (flags)
{
*flags = (TMXTileFlags)(tile & kTMXFlipedAll);
}
return (tile & kTMXFlippedMask);
}
所以,我很困惑,因为地图似乎在内存中表示为数组。
为什么可能?这对我很重要,因为你知道平铺地图可能非常大。关于大小的地图是什么:1000000个瓷砖x 1000000个瓷砖。结果我们应该采用1000000 ^ 2个Tile元素,因此我们需要一个非常长的连续内存块。但是不可能获得如此大的内存(是否可能?)。
请解释一下。
答案 0 :(得分:2)
不要一次将所有地图放入内存。无论如何,玩家几乎无法看到所有这些。相反,只有玩家所在的牌,以及玩家周围所有方向的一定数量的牌。
然后,当玩家移动时,从您在磁盘上的任何地图加载新的磁贴信息,或者如果您执行程序磁贴,则生成,将内存中的磁贴替换为您加载/生成的新磁贴。
答案 1 :(得分:1)
根据MSDN:
进程的虚拟地址空间是它可以使用的一组虚拟内存地址。每个进程的地址空间都是私有的,除非共享,否则其他进程无法访问。 虚拟地址不代表对象在内存中的实际物理位置;相反,系统为每个进程维护一个页表,这是一个内部数据结构,用于将虚拟地址转换为相应的物理地址。每次线程引用地址时,系统都会将虚拟地址转换为物理地址。
所以分配大型数组没有问题,但仍有机会进入hip memory fragmentation