нужен тип данных с возможностью изменения размера для системы координат xy - PullRequest
1 голос
/ 02 января 2011

Я пишу программу для изменения отдельных фрагментов простой трехмерной игровой карты ( minecraft ). Карта может быть теоретически очень большой , поэтому загрузка всей карты исключена. Я хочу загрузить каждый блок размером 16x16 раз и сохранить эти фрагменты в памяти, если мне потребуется изменить его снова. Мне нужна структура данных, чтобы хранить эти части в памяти в виде координат (x, y), и при этом иметь возможность изменять размер этой структуры данных по мере необходимости и упорядочивать ее, чтобы я мог находить определенные фрагменты. Я не знаю, какую структуру данных я мог бы использовать для удовлетворения своих требований. Я надеюсь, что кто-то может сделать некоторые предложения. Я кодирую в C #.

1 Ответ

4 голосов
/ 02 января 2011

Я рекомендую структуру данных верхнего уровня 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 };
    }
}
...