简体   繁体   English

一个很大的数组(连续的内存块)

[英]A very big array ( continuous chunk of memory)

I'm learning Cocos2dx and I'm using tiled map. 我正在学习Cocos2dx,正在使用平铺地图。 So, let consider a following piece of code: 因此,让我们考虑以下代码:

 auto map = TMXTiledMap::create("map.tmx");
 auto layer = map->getLayer("Tile Layer 1");   
 auto gid = layer->tileGIDAt(Point(X, Y));

And last line matters to me. 最后一行对我很重要。 I'm confused because I saw implementation of tileGIDAt(Point): 我很困惑,因为我看到了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);
}

So, I am confused because the map seems to be represented as array in memory. 因此,我很困惑,因为映射似乎被表示为内存中的数组。

Why is it possible? 为什么可能呢? It matters to me because as you know tiled map may be very large. 这对我很重要,因为您知道平铺的地图可能很大。 And what's about map of size: 1000000 tiles x 1000000 tiles. 大小地图的大小是:1000000瓷砖x 1000000瓷砖。 In a result we should take a 1000000^2 elements of Tile, so we need a very long continuous chunk of memory. 结果,我们应该使用1000000 ^ 2个Tile元素,因此我们需要很长的连续内存块。 But it is impossible to get such big chunk of memory ( is it possible?). 但是不可能获得这么大的内存(可能吗?)。

Please explain me. 请给我解释一下。

Don't put all of the map into memory at once. 不要将所有地图立即存储到内存中。 The player is hardly going to be able to see all of it anyway. 无论如何,玩家几乎都无法看到所有内容。 Instead have just the tile the player is on, plus a certain amount of tiles in all directions around the player. 取而代之的是只有玩家所在的瓷砖,再加上玩家周围各个方向的一定数量的瓷砖。

Then as the player moves, load new tile information from whatever map you have on disk, or generate if you do procedural tiles, replacing the tiles in memory with the new one you load/generate. 然后,随着播放器的移动,从磁盘上的任何映射加载新的瓦片信息,或者如果您要进行程序化的瓦片,则生成新的瓦片信息,用加载/生成的新瓦片替换内存中的瓦片。

According to the MSDN: 根据MSDN:

The virtual address space for a process is the set of virtual memory addresses that it can use. 进程的虚拟地址空间是它可以使用的一组虚拟内存地址。 The address space for each process is private and cannot be accessed by other processes unless it is shared. 每个进程的地址空间都是私有的,除非共享它,否则其他进程将无法访问该地址空间。 A virtual address does not represent the actual physical location of an object in memory; 虚拟地址并不代表对象在内存中的实际物理位置; instead, the system maintains a page table for each process, which is an internal data structure used to translate virtual addresses into their corresponding physical addresses. 相反,系统为每个进程维护一个页表,该页表是一种内部数据结构,用于将虚拟地址转换为相应的物理地址。 Each time a thread references an address, the system translates the virtual address to a physical address. 每次线程引用一个地址时,系统都会将虚拟地址转换为物理地址。

So there is no problem with allocation of huge arrays, but there still is chance to get into hip memory fragmentation 因此,分配大型数组没有问题,但仍有机会陷入髋部记忆碎片

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM