【发布时间】:2010-03-15 04:56:16
【问题描述】:
我正在开发一款游戏,其中存在运动图像的碰撞检测问题。游戏中有一艘宇宙飞船和许多小行星(障碍物)。我想检测它们之间的碰撞。我该怎么做?
【问题讨论】:
我正在开发一款游戏,其中存在运动图像的碰撞检测问题。游戏中有一艘宇宙飞船和许多小行星(障碍物)。我想检测它们之间的碰撞。我该怎么做?
【问题讨论】:
对于矩形以外的任何东西,碰撞检测通常都很棘手。
我过去这样做的方式是为每个对象提供图像和蒙版。例如,来自Lost in Space 的像 Jupiter 2 宇宙飞船这样的物体将具有以下图像和掩码:
X 00000100000
XXXXXXX 00111111100
X X 01111111110
X X 11111111111
X X 01111111110
XXXXXXX 00111111100
XXX 00001110000
image 是在屏幕上显示的,而 mask 是用于碰撞检测的。您会注意到掩码中的 1 基本上是图像的轮廓和内容。
检测碰撞的方式:
这会考虑到“几乎未命中”,即每个对象的边界矩形重叠,但不一定是对象自身的轮廓。位运算符是检测这一点的有效方法。
这是一个箭头没有完全击中气球的示例 - 在我的图形设计技能面前颤抖:
....xx....
..xx..xx..
.x......x.
.x......x.
x........x
x........x
.x......x.
.x......x.
..xx..xx..
....xx.**y.....
.y......
yyyyyyyy
.y......
..y.....
您可以看到,即使矩形重叠(请参阅**y),箭头实际上并没有与气球接触。通过对掩码应用按位与运算,这些位最终将为零,从而导致不冲突。
@kyoryu 在他的评论中提出了一个有趣的观点。一些游戏很好地适应了由较小的矩形组成的对象,您可以简化基于矩形组件的碰撞检测(无需担心像素完美)。例如,我们的老朋友太空侵略者(实际上是那个游戏中对抗太空侵略者的防御者)可能由两个矩形组成,X 和 Y,导弹由 Z 组成:
YYYY .Z.
YYYY .Z.
XXXXXXXXXXXX .Z.
XXXXXXXXXXXX ZZZ
XXXXXXXXXXXX .Z.
XXXXXXXXXXXX
这将归结为导弹与两个太空入侵者矩形的简单矩形检查 - 考虑到导弹的大小,即使您接触到 . 字符之一(考虑它们),您也可能将其称为碰撞近程导弹,而不是冲击型导弹)。
【讨论】:
对于像这样的简单游戏,我发现使用圆圈可以很容易地检测碰撞。我们可以使用Pythagorean Theorem for triangles
c^2 = a^2 + b^2
我们可以通过知道如果中心之间的距离小于它们必须碰撞的组合半径来检测两个圆之间的碰撞,对吗?然后您可以像这样进行碰撞检查:
distX ^ 2 + distY ^ 2 <= (radius1 + radious2) ^ 2 == COLLISION!
distX 和 distY 是两个圆的中心之间的距离,除非圆的大小发生变化,否则可以预先计算半径 1 + 半径 2 的平方。
使用圆形的好处是计算对象如何相互反弹也比使用正方形或矩形要容易得多。
【讨论】:
与盒子发生碰撞很容易。如果你只看 x 轴,两个盒子有三种可能的排列方式:
如果第一个盒子在第二个盒子的左边,这意味着它的最右边的点必须在第二个盒子最左边的点的左边。
first.right < second.left
如果第一个盒子在第二个盒子的右边,它的最左边点必须在第二个盒子最右边点的右边。
first.left > second.right
如果这些都不成立,则框会在 x 轴上重叠。
然后,您可以对 y 平面重复此操作(用顶部和底部代替左右),以确定框是否也在 y 轴上重叠 - 如果重叠,则它们正在碰撞!这就是 2d 游戏中简单碰撞所需要做的全部事情。
可能会出现更大的问题,具体取决于您拥有多少不同的对象,因为碰撞检测的简单实现是 O(N^2) 算法。
【讨论】:
检测两个图像的 X 和 Y,然后进行一些计算,如果它们的大小不同,则减去每个图像的宽度和高度,以获得正确的 x 和 y 坐标。 示例:
|------- | | | | | | |_______| ` | | | | 下来 |----------| | | | | | | |----------| 减去宽度和高度以找出正确的 x 和 y【讨论】:
您可以使用 Java 内置的矩形交集。它甚至适用于旋转的矩形。
创建矩形并确保它跟随对象的旋转和位置。
每帧调用它的rectangle.intersects(Rectangle)方法,看看它是否相交。
使用多个矩形可以为奇怪形状的图像创建更好的命中框。
【讨论】: