Java游戏中的碰撞检测?

发布于 2024-08-24 22:57:58 字数 72 浏览 6 评论 0原文

我正在开发一款游戏,其中存在运动图像碰撞检测的问题。游戏有一艘宇宙飞船和一些小行星(障碍物)。我想检测它们之间的碰撞。我该怎么做?

I am developing a game in which I have the problem of collision detection of moving images. The game has a spaceship and number of asteroids (obstacles). I want to detect the collision between them. How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

神魇的王 2024-08-31 22:57:58

对于矩形以外的任何物体,碰撞检测通常都很棘手。

我过去这样做的方法是为每个对象提供图像和蒙版。例如,迷失在太空中的木星 2 号宇宙飞船等物体将具有以下图像和遮罩:

     X            00000100000
  XXXXXXX         00111111100
 X       X        01111111110
X         X       11111111111
 X       X        01111111110
  XXXXXXX         00111111100
    XXX           00001110000

图像是显示到屏幕上的内容,而遮罩是用于碰撞检测的内容。您会注意到掩码中的 1 基本上是图像的轮廓和内容。

检测碰撞的方式:

  • 检查矩形是否重叠。如果没有,就不会有碰撞的机会。
  • 否则创建一个由其蒙版组成的对象编号 1 的矩形。
  • 构造另一个由对象 2 的蒙版组成的矩形。
  • 矩形 2 与矩形 1 的重叠部分按位与。
  • 如果矩形 1 中剩余任何 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

例如,我们的老朋友太空入侵者(实际上是游戏中对抗太空入侵者的 到导弹与两个太空入侵者矩形的简单矩形检查 - 考虑到导弹的大小,即使您接触 . 字符之一(考虑它们接近),您也可能将其称为碰撞导弹而不是撞击型导弹)。

Collision detection is generally tricky for anything other than rectangles.

The way I've done this in the past is to provide both an image and a mask for each object. So for example, an object like the Jupiter 2 spaceship from Lost in Space would have the following image and mask:

     X            00000100000
  XXXXXXX         00111111100
 X       X        01111111110
X         X       11111111111
 X       X        01111111110
  XXXXXXX         00111111100
    XXX           00001110000

The image is what gets blatted to the screen but the mask is what's used for collision detection. You'll notice that the 1's in the mask are basically the outline and contents of the image.

The way in which you detect collision:

  • check if the rectangles overlap. If not, there can be no chance of collision.
  • Otherwise create a rectangle of object number 1 consisting of its mask.
  • Construct another rectangle of object 2 consisting of its mask.
  • Bitwise-AND the overlapping part of rectangle 2 with rectangle 1.
  • If there are any 1-bits left in rectangle 1, you have collision.

This takes into account "near misses" where the bounding rectangles of each object overlap but not necessarily the object outlines themselves. Bitwise operators are an efficient way to detect this.

Here's an example of an arrow not quite hitting a balloon - tremble before my graphical design skills:

....xx....
..xx..xx..
.x......x.
.x......x.
x........x
x........x
.x......x.
.x......x.
..xx..xx..
....xx.**y.....
       .y......
       yyyyyyyy
       .y......
       ..y.....

You can see that, even though the rectangles overlap (see **y), the arrow has not actually made contact with the balloon. By applying the bitwise AND operation to the masks, those bits will end up as zero, resulting in a non-collision.


And @kyoryu raises an interesting point in his comment. Some games adapt well to having objects made up off smaller rectangles and you can simplify collision detection based on the rectangular components (without worrying about pixel perfection). For example, our old friend the space invader (actually the defender against the space invaders in that game) may be made up of two rectangles, X and Y with the missiles being made from Z:

    YYYY                .Z.
    YYYY                .Z.
XXXXXXXXXXXX            .Z.
XXXXXXXXXXXX            ZZZ
XXXXXXXXXXXX            .Z.
XXXXXXXXXXXX

This would come down to a simple rectangular check of the missile against the two space invader rectangles - Given the size of the missile, you could probably call it a collision even if you contact one of the . characters (consider them proximity missiles rather than those of the impact variety).

触ぅ动初心 2024-08-31 22:57:58

对于像这样的简单游戏,我发现使用圆圈可以非常容易地检测碰撞。我们可以利用三角形勾股定理

c^2 = a^2 + b^2

我们可以通过以下方式检测两个圆之间的碰撞知道如果中心之间的距离小于组合半径,它们一定会发生碰撞,对吧?然后,您可以像这样进行碰撞检查:

distX ^ 2 + distY ^ 2 <= (radius1 + radious2) ^ 2 == COLLISION!

distX 和 distY 是两个圆的中心之间的距离,并且可以预先计算半径 1 + 半径 2 的平方,除非圆的大小发生变化。

使用圆形的一个好处是计算物体如何相互反弹也比使用正方形或矩形容易得多。

For simple games like this I find using circles makes detecting collisions very easy. We can make use of the Pythagorean Theorem for triangles

c^2 = a^2 + b^2

We can detect collision between two circles by knowing the that if the distance between the centers is less the the combined radius they must be colliding, right? You can then do a collision check like this:

distX ^ 2 + distY ^ 2 <= (radius1 + radious2) ^ 2 == COLLISION!

distX and distY are the distance between the centers of the two circles and the radius1 + radius2 squared can be pre-calculated unless the circle sizes are changing.

A nice thing about using circles is calculating how objects bounce off each other is also much easier than with square or rectangles.

扮仙女 2024-08-31 22:57:58

与盒子发生碰撞是很容易的。如果仅查看 x 轴,两个框可能存在三种排列方式:

  1. 重叠
  2. 第一个框位于第二个框的左侧
  3. 第一个框位于第二个框的右侧。

如果第一个框位于第二个框的左侧,则意味着其最右边的点必须位于第二个框最左点的左侧。

first.right < second.left

如果第一个框位于第二个框的右侧,则其最左边的点必须位于第二个框最右点的右侧。

first.left > second.right

如果这两个都不成立,则这些框在 x 轴上重叠。

然后,您可以在 y 平面上重复此操作(用顶部和底部代替左侧和右侧),以查明这些框是否也在 y 轴上重叠 - 如果重叠,则它们正在碰撞!这确实是 2d 游戏中简单碰撞所需要做的全部工作。

更大的问题可能会出现,具体取决于您有多少不同的对象,因为碰撞检测的简单实现是 O(N^2) 算法。

It's pretty easy to do collision with boxes. If you look at just the x axis, there's three possible arrangements for two boxes to be in:

  1. Overlapping
  2. The first box is to the left of the second one
  3. The first box is to the right of the second one.

If the first box is to the left of the second one, that means that its rightmost point must be to the left of the second box's leftmost point.

first.right < second.left

If the first box is to the right of the second one, its leftmost point must be to the right of the second box's rightmost point.

first.left > second.right

If neither of these are true, then the boxes overlap on the x axis.

You can then repeat this for the y plane (substituing top and bottom for left and right) to find out if the boxes also overlap on the y axis - if they do, they are colliding! And that's really all you need to do for simple collisions in a 2d game.

The bigger problem may come up depending on how many different objects you have, as the naive implementation of collision detection is an O(N^2) algorithm.

挖个坑埋了你 2024-08-31 22:57:58

检测两个图像的 X 和 Y,然后进行一些计算减去每个图像的宽度和高度(如果它们的大小不同)以获得正确的 x 和 y 坐标。
例子:

|-------
|   |
|   |
|   |
|_______|

`    |
    |
    |
    |
comming down



      |---------|
      |     |
      |     |
      |     |
      |---------|
Minus width and height to find out correct x and y


Detect the X and Y of both images and then do some calculation minus width and height of each images if they are of not same size to get correct x and y coordinates.
Example:

|-------
|   |
|   |
|   |
|_______|

`    |
    |
    |
    |
comming down



      |---------|
      |     |
      |     |
      |     |
      |---------|
Minus width and height to find out correct x and y


梦里°也失望 2024-08-31 22:57:58

如果您愿意这样做,JBox2D 是一个令人惊叹的物理引擎,旨在帮助解决这个问题。它会为你处理所有的物理问题,你所要做的就是在它告诉你的地方绘制图像。

我个人现在一直在使用它。我确实发现开始使用有点困难,但是一旦你开始记住如何制作一个物体,它就会变得非常容易。

您可以在此处下载它。

此处还提供了一些有关基础知识的视频。他使用的库有点“乏善可​​陈”,但你可以轻松理解基础知识。

If you are willing to do so, JBox2D is an amazing physics engine designed to help with just this problem. It handles all the physics for you and all you have to do is draw images where it tells you to.

I personally use it all the time now. I did find it slightly difficult to start using but once you start to memorise how to make an object, it get very easy.

You can download it here.

There are also some videos on basics here. The library he uses is a bit "wishy washy" but you can easily understand the basics.

挥剑断情 2024-08-31 22:57:58

您可以使用 Java 内置的矩形交叉点。它甚至适用于旋转的矩形。

  1. 创建矩形并确保它遵循对象的旋转和位置。

  2. 每帧调用 rectangle.intersects(Rectangle) 方法来确定它是否相交。

使用多个矩形可以让您为形状奇怪的图像创建更好的命中框。

You can use Java's built in rectangle intersections. It works even for rotated rectangles.

  1. Create the rectangle and make sure it follows the object's rotation and position.

  2. Call the rectangle.intersects(Rectangle) method on it every frame to find out if it is intersecting.

Using multiple rectangles allows you to create a better hit box for oddly shaped images.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文