简体   繁体   English

Java游戏中的碰撞检测?

[英]Collision detection in Java game?

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? 我怎样才能做到这一点?

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: 因此,例如,像Lost in Space中的Jupiter 2太空船这样的物体将具有以下图像和掩模:

     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. 您会注意到蒙版中的1基本上是图像的轮廓和内容。

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. 否则,创建一个由其掩码组成的对象编号1的矩形。
  • Construct another rectangle of object 2 consisting of its mask. 构造另一个由其掩码组成的对象2矩形。
  • Bitwise-AND the overlapping part of rectangle 2 with rectangle 1. 按位-AND矩形2与矩形1的重叠部分。
  • If there are any 1-bits left in rectangle 1, you have collision. 如果矩形1中还有1位,则表示存在碰撞。

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. 你可以看到,即使矩形重叠(见**y ),箭头实际上并没有与气球接触。 By applying the bitwise AND operation to the masks, those bits will end up as zero, resulting in a non-collision. 通过对掩码应用按位AND运算,这些位将最终为零,从而导致非冲突。


And @kyoryu raises an interesting point in his comment. @kyoryu在他的评论中提出了一个有趣的观点。 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: 例如,我们的老朋友太空入侵者(实际上是该游戏中对抗太空入侵者的防守者 )可能由两个矩形组成,X和Y,导弹由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). 角色(考虑它们是近距离导弹,而不是影响变种的导弹)。

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. distX和distY是两个圆的中心之间的距离,并且除非圆的大小正在改变,否则可以预先计算radius1 + radius2的平方。

A nice thing about using circles is calculating how objects bounce off each other is also much easier than with square or rectangles. 使用圆形的一个好处是计算物体彼此反弹的方式也比使用方形或矩形更容易。

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: 如果仅查看x轴,则可以安排两个盒子:

  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. 如果这些都不是真的,则框在x轴上重叠。

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! 然后,您可以对y平面重复此操作(替换左侧和右侧的顶部和底部),以确定框架是否也在y轴上重叠 - 如果它们相同,则它们会发生碰撞! And that's really all you need to do for simple collisions in a 2d game. 对于2D游戏中的简单碰撞,这就是你真正需要做的。

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. 更大的问题可能取决于您拥有多少个不同的对象,因为碰撞检测的天真实现是O(N ^ 2)算法。

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. 检测两个图像的X和Y,然后进行一些计算减去每个图像的宽度和高度,如果它们的大小不同,则得到正确的x和y坐标。 Example: 例:

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

`    |
    |
    |
    |
comming down



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

If you are willing to do so, JBox2D is an amazing physics engine designed to help with just this problem. 如果你愿意这样做,JBox2D是一个惊人的物理引擎,旨在帮助解决这个问题。 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. 他使用的图书馆有点“愚蠢”,但你可以很容易地理解基础知识。

You can use Java's built in rectangle intersections. 您可以使用Java的内置矩形交叉点。 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. 每帧调用rectangle.intersects(Rectangle)方法,以确定它是否相交。

Using multiple rectangles allows you to create a better hit box for oddly shaped images. 使用多个矩形可以为奇怪形状的图像创建更好的命中框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM