xy 坐标系需要可调整大小的数据类型

发布于 2024-10-09 16:04:01 字数 441 浏览 2 评论 0原文

我正在编写一个程序来修改简单 3D 游戏地图的选定块 (我的世界)。该地图理论上非常大,因此加载整个地图地图是不可能的。我只想加载每个 16x16 大小的块一次,并将这些块保留在内存中,以便我需要再次修改它。我需要一个数据结构来以 (x,y) 坐标方式将这些部分存储在内存中,同时能够根据需要调整该数据结构的大小并保持其有序,以便我可以找到特定的块。 我不知道可以使用什么数据结构来满足我的要求。我希望有人可以提出一些建议。我正在用 c# 编码。

I am coding a program to modify select chunks of a simple 3d game map (minecraft). The map can be theoretically very large so loading the entire map is out of the question. I want to only load each 16x16 sized chunk once and have those chunks in memory should I need to modify it again. I need a data structure to store these portions in memory in an (x,y) coordinate fashion while being able to resize this data structure as needed and keep it orderly so I can find specific chunks.
I am at a loss on what data structure I could use to meet my requirements. I am hoping someone could make some suggestions. I am coding in c#.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绮筵 2024-10-16 16:04:01

我建议使用顶级 Map 数据结构,该结构具有基于坐标 的索引器。接下来添加一个 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 };
    }
}

I recommend a top level Map data structure that has an indexer based on a Coordinate. Next add a Chunk data structure which is like a miniature map. In the accessors for the Map indexer, check whether the chunk that contains the coordinate is loaded and if not load it. Then delegate the Map indexer to the Chunk indexer. The Map can keep track of which chunks are loaded using a Dictionary. Finally, you need to unload chunks based on a strategy, e.g. least recently used.

With this infrastructure in place you can then use the Map as a virtual infinite plane.

Here's some (untested) pseudo-code to get you started:

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 };
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文