我正在开发一款游戏,其中遇到了移动图像的碰撞检测问题。这个游戏有一个宇宙飞船和若干个小行星(障碍物)。我想要检测它们之间的碰撞。我该怎么做呢?
我正在开发一款游戏,其中遇到了移动图像的碰撞检测问题。这个游戏有一个宇宙飞船和若干个小行星(障碍物)。我想要检测它们之间的碰撞。我该怎么做呢?
除了矩形之外,一般来说,检测碰撞是很棘手的。
我过去处理这个问题的方式是为每个对象提供图像和掩码。例如,像迷失太空中的木星2号宇宙飞船这样的对象将具有以下图像和掩码:
X 00000100000
XXXXXXX 00111111100
X X 01111111110
X X 11111111111
X X 01111111110
XXXXXXX 00111111100
XXX 00001110000
< p > Image 是显示在屏幕上的内容,但是掩码是用于碰撞检测的。您会注意到掩码中的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
),箭头也没有实际接触气球。将按位 AND 操作应用于掩码,这些位最终会变为零,导致无碰撞。
在他的评论中,@kyoryu提出了一个有趣的观点。一些游戏适合使用由较小矩形组成的对象,并且您可以根据矩形组件简化碰撞检测(而不必担心像素完美)。例如,我们的老朋友太空入侵者(实际上是该游戏中太空入侵者的防御者)可能由两个矩形X和Y组成,导弹由Z制成:
YYYY .Z.
YYYY .Z.
XXXXXXXXXXXX .Z.
XXXXXXXXXXXX ZZZ
XXXXXXXXXXXX .Z.
XXXXXXXXXXXX
。
字符(将其视为接近导弹而不是撞击类型),您也可以称之为碰撞。对于像这样简单的游戏,我发现使用圆形可以很容易地检测到碰撞。我们可以利用勾股定理来处理三角形。
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轴上发生重叠 - 如果是,则它们正在碰撞!这基本上是你在二维游戏中所需做的全部内容。
更大的问题可能会出现在你拥有多少不同的对象上,因为碰撞检测的天真实现是O(N ^ 2)算法。
你可以使用Java内置的矩形相交功能,即使是旋转的矩形也适用。
创建矩形并确保其遵循对象的旋转和位置。
每帧调用rectangle.intersects(Rectangle)
方法来查找是否相交。
使用多个矩形可以为奇形怪状的图像创建更好的命中框。