我正在制作一个世界向各个方向无限延伸的游戏。这意味着您可以在位置X:50
,Y:50
或X:-50
, Y:-50
。但是......我真的不能用普通的 C# 列表做到这一点......
我提出的所有想法似乎都太复杂/效率低下无法工作......
实现无限网格的最简单方法是使用带有字典的稀疏矩阵,其中 x,y 对作为键,您要存储的数据作为值。如果您的网格是稀疏的,这将快速、易于实现且内存友好。
另一种方法是链接网格(类似于链表,但具有指向 4 个方向的指针),或基于瓦片的方法来减少链接网格的开销(瓦片是 NxN 数组的链接网格)。瓦片的实现相当复杂,但是对于非常密集的网格来说,它是内存和性能之间的良好折衷。
但我个人最喜欢的方法是使用奇偶变换。所以奇数指数是正数,而偶数指数是负数。要从虚拟索引转换为物理索引,请使用公式p = abs(v * 2) - (v > 0 ? 1 : 0)
并将物理索引转换为虚拟索引 v = (p % 2 == 1 ? +1 : -1) * ((2*p + 3) / 4)
。这种关系的出现是因为自然数和整数之间存在一对一的关系(双射)(0 <-> 0), (1 <-> 1), (2 <-> -1), (3 <-> 2), (4 <-> -2), (5 <-> 3), (6 <-> -3), ...
。这种方法快速、简单且优雅,但当您的网格非常稀疏且项目离中心线极远时,这种方法的记忆力就不是很好。
除非你有一个 TON(是的,一个 TON 的位......)的单元格,否则你可以使用字典。将它与 aSystem.Drawing.Point
作为键相结合,你会得到一件好事:
Dictionary<Point,YourGridObject> myMap = new Dictionary<Point,YourGridObject>();
编辑:除了字典,每个单元格都可以引用它的相邻单元格,这样你可以使用字典直接去“某处”,然后用相邻的导航。我用这种方式在一个十六进制网格中实现了一个 A* 寻路算法。
编辑2:例如,如果你想访问一个特定的坐标,你可以简单地
var myTile = myMap[new Point(25, -25)];
然后,你想得到East
瓷砖,你可以
var eastTile = myTile.East;
您的网格对象还可以实现偏移方法,因此您可以通过
var otherTile = myTile.Offset(-2, 5);
如何在下面使用两个 List 进行两个不同方向的扩展?
我不确定这是否比您想要处理的更复杂,但是您是否考虑过使用极坐标而不是笛卡尔坐标?该坐标系中没有负数。我意识到一开始覆盖很难,但是一旦你把头绕在它周围,它就变成了第二天性。
您可以使用 Dictionary,它具有数组的所有功能,但显然带有负索引。
计算机无法存储无限数组。您的数组必须有一个边界,请提醒您在数组初始化期间在代码中的某处声明了特定大小。也许你在某个地方调整它的大小,但这仍然留下一个从 0.. 到.. 最大的数字范围。
所以你应该做的是,编写一个允许在这样的地图中进行相对定位的函数。因此,您将当前的地图 [x,y] 存储为位置。并且您可以通过具有相对于您当前位置添加/减去的功能来上升。这也使您的代码更易于理解。
如果您处理的不是游戏地图而是数字范围,假设您可以创建一个包含 n 个点的列表或一个 2d 字典的向量。
我在这里发布它,因为您的问题可能会导致人们编写错误的代码。
在地图周围有边框的情况下(通常在游戏场景和图像处理中)也为其他人添加。您的数据来自 [-1..width+1] 只需将其标注为 [0,width+2]然后从“for (int x = 1; x < Width+1; x++)”开始循环遍历它