如何从/向多个文件读取/写入三维信息?

时间:2014-07-13 11:59:35

标签: c# arrays

我想将我的地图存储到多个文件中,以后能够获取该数据。地图是一种无限的,噪声生成的地图。地图被切成块状。噪声生成参数具有种子值+ 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维。我需要一些可以改变价值观的东西,因为玩家将改变世界。问题是:什么?

1 个答案:

答案 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));

}