我正在编写一个程序来修改一个简单的 3d 游戏地图(minecraft)的选择块。该地图理论上可以非常大,因此加载整个地图是不可能的。我只想加载每个 16x16 大小的块一次,并在需要再次修改时将这些块保存在内存中。我需要一个数据结构以(x,y)坐标方式将这些部分存储在内存中,同时能够根据需要调整此数据结构的大小并使其保持有序,以便我可以找到特定的块。我不知道可以使用什么数据结构来满足我的要求。我希望有人可以提出一些建议。我正在用 c# 编码。
问问题
1638 次
1 回答
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 };
}
}
于 2011-01-02T06:54:21.693 回答