我正在编写一个程序来修改一个简单的 3d 游戏 map (minecraft) 的选定 block 。 map 可以theoretically very large所以加载整个 map 是不可能的。我只想加载每个 16x16 大小的 block 一次,并将这些 block 放在内存中,以便我需要再次修改它。我需要一个数据结构以 (x,y) 坐标方式将这些部分存储在内存中,同时能够根据需要调整此数据结构的大小并保持其有序,以便我可以找到特定的 block 。 我不知道可以使用什么数据结构来满足我的要求。我希望有人可以提出一些建议。我正在用 C# 编写代码。
最佳答案
我推荐一个顶级Map
数据结构,它有一个基于Coordinate
的索引器。接下来添加一个像微型 map 一样的Chunk
数据结构。在 Map
索引器的访问器中,检查是否加载了包含坐标的 block ,如果没有加载它。然后将 Map
索引器委托(delegate)给 Chunk
索引器。 Map
可以使用 Dictionary
跟踪加载了哪些 block 。最后,您需要根据策略卸载 block ,例如最近最少使用。
有了这个基础架构,您就可以将 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 };
}
}
关于c# - xy坐标系需要可调整大小的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4577294/