我正在与一个向各个方向无限延伸的世界进行游戏。这意味着您可以处于X:50
,Y:50
或X:-50
,Y:-50
的位置。但是......我不能用普通的C#List真正做到这一点......
我提出的所有想法似乎都太复杂/无效,无法工作......
答案 0 :(得分: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), ...
之间存在一对一和关系(双射)。这种方法快速,简单,优雅,但如果你的网格非常稀疏,并且距离中心线很远,那么这种方法就不是很好。
答案 1 :(得分:1)
除非您有单元格的TON(是,TON of bits ...),否则您可以使用字典。将其与System.Drawing.Point
组合作为关键,你会得到一件好事:
Dictionary<Point,YourGridObject> myMap = new Dictionary<Point,YourGridObject>();
编辑:除了字典之外,每个单元格都可以引用它的相邻单元格,这样你就可以使用字典直接进入“某处”,然后用相邻的单元格导航。我用这种方式在十六进制网格中实现A *寻路算法。
编辑2: 例如,如果您想要访问特定坐标,则可以简单地
var myTile = myMap[new Point(25, -25)];
然后,您想获得East
磁贴,您可以
var eastTile = myTile.East;
您的网格对象也可以实现偏移方法,以便您可以通过
获取“West 2,North 5”磁贴var otherTile = myTile.Offset(-2, 5);
答案 2 :(得分:0)
如何在两个不同方向上使用两个List进行扩展?
答案 3 :(得分:0)
我不确定这是否比您想要处理的更复杂,但您是否考虑使用极坐标而不是笛卡尔坐标?该坐标系中没有负数。我意识到起初的转变是困难的,但是一旦你绕过它,它就变成了第二天性。
答案 4 :(得分:0)
你可以使用Dictionary,它具有数组的所有功能,但显然是负数索引。
答案 5 :(得分:0)
计算机无法存储无限数组。 数组必须有一个边界,提醒您在数组初始化期间声明了特定大小的代码中的某处。 也许你在某个地方调整它的大小,但是仍然留下0到最大的数字范围
那么你应该做些什么,写一个允许在这样的地图中相对定位的函数。因此,您将当前地图[x,y]存储为位置。 你可以通过一个相对地增加/减少当前位置的功能来提升你的能力。 这样可以使您的代码更易于理解。
如果你没有处理游戏地图而不是数字范围,那么就说矢量 你可以创建一个n点列表,或者一个二维字典。
我在这里发帖,因为你的问题可能会导致人们编写错误的代码。
在地图周围有边框的情况下也可以为其他人添加(通常在游戏场景和图像处理中)。 您的数据来自[-1..width + 1],只需将其标注为[0,width + 2] 然后循环开始'for(int x = 1; x&lt; Width + 1; x ++)'