8

我正在制作一个世界向各个方向无限延伸的游戏。这意味着您可以在位置X:50,Y:50X:-50, Y:-50。但是......我真的不能用普通的 C# 列表做到这一点......

我提出的所有想法似乎都太复杂/效率低下无法工作......

4

6 回答 6

15

实现无限网格的最简单方法是使用带有字典的稀疏矩阵,其中 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), ...。这种方法快速、简单且优雅,但当您的网格非常稀疏且项目离中心线极远时,这种方法的记忆力就不是很好。

于 2012-08-07T00:53:21.323 回答
1

除非你有一个 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);
于 2012-08-07T02:09:59.327 回答
0

如何在下面使用两个 List 进行两个不同方向的扩展?

于 2012-08-07T03:28:06.933 回答
0

我不确定这是否比您想要处理的更复杂,但是您是否考虑过使用极坐标而不是笛卡尔坐标?该坐标系中没有负数。我意识到一开始覆盖很难,但是一旦你把头绕在它周围,它就变成了第二天性。

于 2012-08-23T18:19:38.600 回答
0

您可以使用 Dictionary,它具有数组的所有功能,但显然带有负索引。

于 2013-10-23T00:46:37.083 回答
0

计算机无法存储无限数组。您的数组必须有一个边界,请提醒您在数组初始化期间在代码中的某处声明了特定大小。也许你在某个地方调整它的大小,但这仍然留下一个从 0.. 到.. 最大的数字范围。

所以你应该做的是,编写一个允许在这样的地图中进行相对定位的函数。因此,您将当前的地图 [x,y] 存储为位置。并且您可以通过具有相对于您当前位置添加/减去的功能来上升。这也使您的代码更易于理解。

如果您处理的不是游戏地图而是数字范围,假设您可以创建一个包含 n 个点的列表或一个 2d 字典的向量。

我在这里发布它,因为您的问题可能会导致人们编写错误的代码。

在地图周围有边框的情况下(通常在游戏场景和图像处理中)也为其他人添加。您的数据来自 [-1..width+1] 只需将其标注为 [0,width+2]然后从“for (int x = 1; x < Width+1; x++)”开始循环遍历它

于 2016-03-15T12:50:50.377 回答