1

単純な3Dゲームマップ(minecraft)の選択したチャンクを変更するプログラムをコーディングしています。マップは理論的には非常に大きくなる可能性があるため、マップ全体をロードすることは問題外です。16x16サイズの各チャンクを1回だけロードし、再度変更する必要がある場合に備えて、それらのチャンクをメモリに保持したいと思います。これらの部分を(x、y)座標でメモリに格納すると同時に、必要に応じてこのデータ構造のサイズを変更し、特定のチャンクを見つけることができるように整然と保つことができるデータ構造が必要です。要件を満たすために使用できるデータ構造がわからなくなっています。私は誰かがいくつかの提案をすることができることを望んでいます。私はC#でコーディングしています。

4

1 に答える 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 に答える