需要调整xy坐标系的数据类型

时间:2011-01-02 05:35:42

标签: c# dynamic-data coordinate-systems

我正在编写一个程序来修改一个简单的3D游戏地图(minecraft)的选择块。地图可以是theoretically very large,因此加载整个地图是不可能的。我想只加载每个16x16大小的块一次,如果我需要再次修改它,请将这些块放在内存中。我需要一个数据结构以(x,y)坐标方式将这些部分存储在内存中,同时能够根据需要调整此数据结构的大小并保持其有序,以便我可以找到特定的块。 我对可用于满足我的要求的数据结构感到茫然。我希望有人可以提出一些建议。我在c#编码。

1 个答案:

答案 0 :(得分:4)

我建议使用基于Map的索引器的顶级Coordinate数据结构。接下来添加一个Chunk数据结构,就像一个微型地图。在Map索引器的访问器中,检查是否加载了包含坐标的块,如果没有加载它。然后将Map索引器委托给Chunk索引器。 Map可以使用Dictionary跟踪加载的块。最后,您需要根据策略卸载块,例如最近最少使用。

有了这个基础设施,您就可以使用Map作为虚拟无限平面。

这里有一些(未经测试的)伪代码可以帮助您入门:

public struct Coordinate : IEquatable<Coordinate>
{
    public int X { get; set; }
    public int Y { get; set; }

    public bool Equals(Coordinate other)
    {
        return X == other.X && Y == other.Y;
    }

    public override int GetHashCode()
    {
        return X ^ Y;
    }
}

public class Data
{
    // Map data goes here.
}

public class Chunk
{
    public Coordinate Origin { get; set; }
    public Data[,] Data { get; set; }

    public Data this[Coordinate coord]
    {
        get { return Data[coord.X - Origin.X, coord.Y - Origin.Y]; }
        set { Data[coord.X - Origin.X, coord.Y - Origin.Y] = value; }
    }
}

public class Map
{
    private Dictionary<Coordinate, Chunk> map = new Dictionary<Coordinate,Chunk>();

    public Data this[Coordinate coord]
    {
        get
        {
            Chunk chunk = LoadChunk(coord);
            return chunk[coord];
        }
        set
        {
            Chunk chunk = LoadChunk(coord);
            chunk[coord] = value;
        }
    }

    private Chunk LoadChunk(Coordinate coord)
    {
        Coordinate origin = GetChunkOrigin(coord);
        if (map.ContainsKey(origin))
        {
            return map[origin];
        }
        CheckUnloadChunks();
        Chunk chunk = new Chunk { Origin = origin, Data = new Data[16, 16] };
        map.Add(origin, chunk);
        return chunk;
    }

    private void CheckUnloadChunks()
    {
        // Unload old chunks.
    }

    private Coordinate GetChunkOrigin(Coordinate coord)
    {
        return new Coordinate { X = coord.X / 16 * 16, Y = coord.Y / 16 * 16 };
    }
}