我想将我的地图存储到多个文件中,以后能够获取该数据。地图是一种无限的,噪声生成的地图。地图被切成块状。噪声生成参数具有种子值+ XYZ,因此我可以轻松地再次重新生成相同的块。每个块都有自己的c#脚本,它有三维bytearray map [x,y,z],值会告诉我哪个块属于那个点。 XYZ坐标是世界坐标而不是大块坐标,这意味着即使我将它们组合在一起,也不会有相同的地图[x,y,z]值。
我希望这个应用程序也可以在移动平台上使用,所以我想在我的应用程序专用服务器中生成地图,并在请求时通过网络发送块数据。虽然这降低了客户端的CPU使用率,但它也为我提供了针对黑客的额外安全性。 (我可以运行检查,如果玩家正在有效地加载块,玩家将无法扫描整个地图并查看所有好东西的位置等)。
我读过有关将多维bytearray存储到文件中并稍后从中读取的内容。我可以很容易地获取块XYZ位置并将其放入文件名中,以便例如块0,0,0数据将被写入chunk_0_0_0.chunk文件。我可以将该块数据存储到文件中,因为我知道块大小及其位置。
这是我目前未经测试的代码:
// Check if chunk 0,0,1 exists, if not then nothing has been yet generated!
if(!File.Exists("world\\chunk_0_0_1.chunk")){
generateChunk(0,0,1);
saveMapToFile();
}
foreach (string file in Directory.EnumerateFiles("world\\", "*.chunk"))
{
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("world\\" + file, FileMode.Open, FileAccess.Read))
{
byte[,,] tempArray = (byte[,,])formatter.Deserialize(stream);
}
}
return true;
我有一个字节(public static byte[,,] map; map[0,0,1] = 0; map[0,1,1] = 4;
等),我想存储每个块数据,以便客户可以轻松获取一张地图及其类型。由于这是无限的地形,当玩家探索更多时,地图将会超时。由于我无法调整字节大小并为其添加更多值,因此我还需要其他内容。我需要能够存储每个块位置及其值的东西。我不能使用List或Dictionary,因为它们不支持3维。我需要一些可以改变价值观的东西,因为玩家将改变世界。问题是:什么?
答案 0 :(得分:1)
您可以简单地将块类型字节以x,z,y顺序存储在常规字节数组中。然后,您可以通过其坐标获取数组中任何块的索引。获得数组索引后,可以使用索引获取并设置块类型值。这是一个例子:
public class Chunk
{
// Maximum values for directions within a chunk.
// Change these to suit your implementation
private static readonly byte _xLength = 32;
private static readonly byte _yLength = 32;
private static readonly byte _zLength = 32;
private byte[] _buffer;
// For creating a brand new Chunk
public Chunk()
{
_buffer = new byte[_xLength * _yLength * _zLength];
}
// Used by Load();
private Chunk(byte[] buffer)
{
_buffer = buffer;
}
// Loads a Chunk from file
public static Chunk Load(string filePath)
{
return new Chunk(File.ReadAllBytes(filePath));
}
// Saves the Chunk to file
public void Save(string filePath)
{
File.WriteAllBytes(filePath, _buffer);
}
// Gets a value in the buffer for coordinate
public byte GetBlock(byte x, byte y, byte z)
{
int offset = GetOffset(x, y, z);
return _buffer[offset];
}
// Sets a value in the buffer for coordinate
public void SetBlock(byte x, byte y, byte z, byte value)
{
int offset = GetOffset(x, y, z);
_buffer[offset] = value;
}
// Get the location in the buffer for coordinate
private static int GetOffset(byte x, byte y, byte z)
{
return (y * _xLength * _zLength) + (z * _xLength) + x;
}
}
然后进行一些测试..
static void Main()
{
// Create a new Chunk
Chunk chunk1 = new Chunk();
// Set some block types in the chunk
chunk1.SetBlock(1, 1, 1, 11);
chunk1.SetBlock(2, 2, 2, 22);
chunk1.SetBlock(3, 3, 3, 33);
// Save it to disk
chunk1.Save("test.chunk");
// Load from disk
Chunk chunk2 = Chunk.Load("test.chunk");
Console.WriteLine("Block at ({0},{1},{2}): {3}", 1, 1, 1, chunk2.GetBlock(1, 1, 1));
Console.WriteLine("Block at ({0},{1},{2}): {3}", 2, 2, 2, chunk2.GetBlock(2, 2, 2));
Console.WriteLine("Block at ({0},{1},{2}): {3}", 3, 3, 3, chunk2.GetBlock(3, 3, 3));
}