在基于网格的级别移动瓷砖的组织系统

Organizational system for moving tiles in grid-based level

这里是概念问题。

我有一个数组,它将被渲染以在网格中显示图块。现在,我希望这些图块能够移动 - 但不仅仅是在网格中移动。每像素。它确实需要是一个网格,因为我需要移动整行的图块,并且能够通过它们的位置访问图块,但它也需要进行逐像素调整,同时仍然保持 "grid" 最高日期。想象一个带有移动方块的平台游戏。

我可以使用一些组织系统来执行此操作,我将概述一些我想到的以及它们的优缺点(XY 样式),以防它帮助您了解我的工作说。我在问你是否认为其中一个是最好的,或者想出更好的方法。

  1. 一种方法是将对象放入具有属性 xOffsetyOffset 的数组中。然后我会在它们的平铺位置加上它们的偏移量渲染它们。 (x * tileWidth + tile.xOffset)。优点:维护香草网格系统。缺点:一旦移动,我就必须将每个图块调整到它的实际网格位置。此外,"grid" 位置会随着方块的移动而变得有点混乱。 (旁注:如果你认为这是一个好方法,我将如何处理碰撞?它不会再像 player.x / tileWidth 那样简单了。)

  2. 另一种方法是放置大量具有 xy 的对象并渲染它们。优点:简单。缺点:然后我必须检查每一个,看看它是否在我想移动的行中,然后再这样做。此外,碰撞不能简单地检查玩家所在的那块地砖,他们必须检查所有实体。

  3. 我想到的另一个是两者的结合。瓷砖将在原始数组中并呈现为 x * tileWidth 普通瓷砖。然后,当它们移动时,它们将从网格中删除并放置在一个单独的数组中用于移动瓷砖,其中存储了它们的 xy。然后碰撞将以快速的方式检查网格,以慢速的方式检查移动的瓷砖。

谢谢!

PS:我正在使用 JavaScript,但它不应该是相关的。

PPS:如果不是Stack Overflow material请见谅。这是最合适的,我想。它不完全是代码审查,但它不特定于 GameDev。我还需要一个标签,所以我选择了一个有点相关的标签。如果你们推荐其他东西,我会很乐意立即切换并删除这个。

PPPS:抱歉,如果转载,我没有知道如何google这个问题。我试过了没有用。

(关于处理碰撞的旁注:你的障碍物在移动。因此,将玩家的位置与网格进行比较是不够的。此外,你将始终必须根据对象的当前位置进行绘制。这两者都是不可避免,但也不是很贵。)

您希望对象易于查找,同时仍然能够高效地绘制它们,更重要的是,快速检查碰撞。这很容易做到:将对象存储在数组中,并为 X 和 Y 位置保留索引,以便 1) 有效地查询范围和 2) 有效地左右移动元素(当它们的 x 和 y 位置发生变化时)。

如果你的对象将移动得相当慢(也就是说,在任何 one 时间步上,一个对象不太可能传递很多其他对象),你的索引可以是数组!当一个对象移过另一个对象时(例如,在 X 中),您只需要在 X 索引数组中检查它的邻居,看看它们是否应该交换位置。继续这样做,直到不需要交换为止。如果他们移动缓慢,摊销成本将非常接近 O(1)。在数组中查询范围非常容易;二进制搜索第一个更大的元素,以及最后一个更小的元素。

Summary/Implementation: (Fiddle 在 https://jsfiddle.net/LsfuLo9p/3/

初始化(O(n)次):

  1. 创建一个名为 Objs.
  2. 的对象数组
  3. 制作一个数组(x位置,参考Objs)对,按X排序,称为Xs.
  4. 制作一个(y位置,参考Objs)对的数组,按Y排序,称为Ys.
  5. 对于 XsYs 中的每个元素,告诉 Objs 中的对象它在这些数组中的索引(以便 Xs 具有 [=19= 的索引] 和 Objs 具有 Xs.)
  6. 的索引

当一个物体在 Y 方向向上移动时(每个移动物体的预期时间为 O(1),假设它们移动缓慢):

  1. 使用Objs,在Ys.
  2. 中找到它的索引
  3. 将其与 Ys. 中的下一个最高值进行比较,如果更大,则在 Ys 中交换它们(并在 Objs 中更新它们的 Y 索引)。
  4. 重复第 2 步,直到不交换为止。

(其他三个方向的应用很简单。)

当玩家移动 (O(log n + k2) 次,其中 k 是一行或一列中可以容纳的最大物品数:

  1. Xs 中查找 small, Player.X, 上方的最小 X 和 large, Player.X. 下方的最大 X+宽度 If largesmall、return范围[large, small].
  2. Ys 中查找 small, Player.Y, 以上的最小 Y 和 large, Player.Y. 以下的最大 Y+高度 I​​f largesmall、return范围[large, small].
  3. 如果这两个范围之间有任何交集,则玩家正在与该对象发生碰撞。

(您可以通过使用哈希图检查集合交集将此时间缩短为 O(log n + k)。)