在基于网格的级别移动瓷砖的组织系统
Organizational system for moving tiles in grid-based level
这里是概念问题。
我有一个数组,它将被渲染以在网格中显示图块。现在,我希望这些图块能够移动 - 但不仅仅是在网格中移动。每像素。它确实需要是一个网格,因为我需要移动整行的图块,并且能够通过它们的位置访问图块,但它也需要进行逐像素调整,同时仍然保持 "grid" 最高日期。想象一个带有移动方块的平台游戏。
我可以使用一些组织系统来执行此操作,我将概述一些我想到的以及它们的优缺点(XY 样式),以防它帮助您了解我的工作说。我在问你是否认为其中一个是最好的,或者想出更好的方法。
一种方法是将对象放入具有属性 xOffset
和 yOffset
的数组中。然后我会在它们的平铺位置加上它们的偏移量渲染它们。 (x * tileWidth + tile.xOffset
)。优点:维护香草网格系统。缺点:一旦移动,我就必须将每个图块调整到它的实际网格位置。此外,"grid" 位置会随着方块的移动而变得有点混乱。 (旁注:如果你认为这是一个好方法,我将如何处理碰撞?它不会再像 player.x / tileWidth
那样简单了。)
另一种方法是放置大量具有 x
和 y
的对象并渲染它们。优点:简单。缺点:然后我必须检查每一个,看看它是否在我想移动的行中,然后再这样做。此外,碰撞不能简单地检查玩家所在的那块地砖,他们必须检查所有实体。
我想到的另一个是两者的结合。瓷砖将在原始数组中并呈现为 x * tileWidth
普通瓷砖。然后,当它们移动时,它们将从网格中删除并放置在一个单独的数组中用于移动瓷砖,其中存储了它们的 x
和 y
。然后碰撞将以快速的方式检查网格,以慢速的方式检查移动的瓷砖。
谢谢!
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)次):
- 创建一个名为
Objs.
的对象数组
- 制作一个数组(x位置,参考
Objs
)对,按X排序,称为Xs.
- 制作一个(y位置,参考
Objs
)对的数组,按Y排序,称为Ys.
- 对于
Xs
和 Ys
中的每个元素,告诉 Objs
中的对象它在这些数组中的索引(以便 Xs
具有 [=19= 的索引] 和 Objs
具有 Xs.
) 的索引
当一个物体在 Y 方向向上移动时(每个移动物体的预期时间为 O(1),假设它们移动缓慢):
- 使用
Objs
,在Ys.
中找到它的索引
- 将其与
Ys.
中的下一个最高值进行比较,如果更大,则在 Ys
中交换它们(并在 Objs
中更新它们的 Y 索引)。
- 重复第 2 步,直到不交换为止。
(其他三个方向的应用很简单。)
当玩家移动 (O(log n + k2) 次,其中 k 是一行或一列中可以容纳的最大物品数:
- 在
Xs
中查找 small,
Player.X,
上方的最小 X 和 large,
Player.X.
下方的最大 X+宽度 If large
≤ small
、return范围[large, small].
- 在
Ys
中查找 small,
Player.Y,
以上的最小 Y 和 large,
Player.Y.
以下的最大 Y+高度 If large
≤ small
、return范围[large, small].
- 如果这两个范围之间有任何交集,则玩家正在与该对象发生碰撞。
(您可以通过使用哈希图检查集合交集将此时间缩短为 O(log n + k)。)
这里是概念问题。
我有一个数组,它将被渲染以在网格中显示图块。现在,我希望这些图块能够移动 - 但不仅仅是在网格中移动。每像素。它确实需要是一个网格,因为我需要移动整行的图块,并且能够通过它们的位置访问图块,但它也需要进行逐像素调整,同时仍然保持 "grid" 最高日期。想象一个带有移动方块的平台游戏。
我可以使用一些组织系统来执行此操作,我将概述一些我想到的以及它们的优缺点(XY 样式),以防它帮助您了解我的工作说。我在问你是否认为其中一个是最好的,或者想出更好的方法。
一种方法是将对象放入具有属性
xOffset
和yOffset
的数组中。然后我会在它们的平铺位置加上它们的偏移量渲染它们。 (x * tileWidth + tile.xOffset
)。优点:维护香草网格系统。缺点:一旦移动,我就必须将每个图块调整到它的实际网格位置。此外,"grid" 位置会随着方块的移动而变得有点混乱。 (旁注:如果你认为这是一个好方法,我将如何处理碰撞?它不会再像player.x / tileWidth
那样简单了。)另一种方法是放置大量具有
x
和y
的对象并渲染它们。优点:简单。缺点:然后我必须检查每一个,看看它是否在我想移动的行中,然后再这样做。此外,碰撞不能简单地检查玩家所在的那块地砖,他们必须检查所有实体。我想到的另一个是两者的结合。瓷砖将在原始数组中并呈现为
x * tileWidth
普通瓷砖。然后,当它们移动时,它们将从网格中删除并放置在一个单独的数组中用于移动瓷砖,其中存储了它们的x
和y
。然后碰撞将以快速的方式检查网格,以慢速的方式检查移动的瓷砖。
谢谢!
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)次):
- 创建一个名为
Objs.
的对象数组
- 制作一个数组(x位置,参考
Objs
)对,按X排序,称为Xs.
- 制作一个(y位置,参考
Objs
)对的数组,按Y排序,称为Ys.
- 对于
Xs
和Ys
中的每个元素,告诉Objs
中的对象它在这些数组中的索引(以便Xs
具有 [=19= 的索引] 和Objs
具有Xs.
) 的索引
当一个物体在 Y 方向向上移动时(每个移动物体的预期时间为 O(1),假设它们移动缓慢):
- 使用
Objs
,在Ys.
中找到它的索引
- 将其与
Ys.
中的下一个最高值进行比较,如果更大,则在Ys
中交换它们(并在Objs
中更新它们的 Y 索引)。 - 重复第 2 步,直到不交换为止。
(其他三个方向的应用很简单。)
当玩家移动 (O(log n + k2) 次,其中 k 是一行或一列中可以容纳的最大物品数:
- 在
Xs
中查找small,
Player.X,
上方的最小 X 和large,
Player.X.
下方的最大 X+宽度 Iflarge
≤small
、return范围[large, small].
- 在
Ys
中查找small,
Player.Y,
以上的最小 Y 和large,
Player.Y.
以下的最大 Y+高度 Iflarge
≤small
、return范围[large, small].
- 如果这两个范围之间有任何交集,则玩家正在与该对象发生碰撞。
(您可以通过使用哈希图检查集合交集将此时间缩短为 O(log n + k)。)