游戏开发基础--碰撞检测

碰撞就是游戏中的元素是否碰到一起,比如打飞机游戏,没躲避炮弹就算碰撞,要检测出来,要game over的。主要讲讲2D游戏里的碰撞检测,传统的2D游戏可以把不同元素当作基本图形粗糙地来检测碰撞与否?

1、矩形判断  

  比如把游戏中敌我双方人物都当作矩形来检测两个矩形是否相交。那么如何判读两个矩形是否相交呢? 

  相交 == !(不相交),不相交较好判断,优先判读不相交再取反就可以了。

  

  如上图旁边矩形都不和中间矩形相交,它们都有共同特点:

  1、旁边矩形(B)的xy坐标没有同时介于中间矩形(A)x~x',y~y'间,即没有一个点出现在A矩形内部,用伪代码判断不相交就是

  B.max(x) < A.min(x) || B.min(x) > A.max(x) || B.max(y) < A.min(y) || B.min(y) > A.max(y)

  那么判读相交的伪代码就是

     !(B.max(x) < A.min(x) || B.min(x) > A.max(x) || B.max(y) < A.min(y) || B.min(y) > A.max(y))

  2、当然由于矩形的特殊性,当知道矩形左上角的坐标和宽高时就可以知道其他三点的坐标,而且左上角坐标一般也是我们绘制矩形要传递的参数。

  

  设两个矩形(A,B)坐标宽高为x1,y1,w1,h1和x2,y2,w2,h2,判断不相交代码就是:

  

复制代码
 1   /**
 2      * 判断两矩形是否相交
 3      */
 4     public boolean isCollsionWithRect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
 5         // 矩形A位于矩形B的右侧
 6         if (x1 >= x2 && x1 >= x2 + w2) {
 7             return false;
 8         // 矩形A位于矩形B的左侧
 9         } else if (x1 <= x2 && x1 + w1 <= x2) {
10             return false;
11         // 矩形A位于矩形B的下侧
12         } else if (y1 >= y2 && y1 >= y2 + h2) {
13             return false;
14         // 矩形A位于矩形B的上侧
15         } else if (y1 <= y2 && y1 + h1 <= y2) {
16             return false;
17         }
18         // 不相交都不满足,那就是相交了
19         return true;
20     }
复制代码

 

  

2、圆形判断

  圆形判读比较简单,即判断两个圆心距离是否大于两个圆的半径之和

复制代码
 1 /**
 2      * 圆形碰撞
 3      * @param x1    圆形1的圆心X坐标
 4      * @param y1    圆形2的圆心X坐标
 5      * @param x2    圆形1的圆心Y坐标
 6      * @param y2    圆形2的圆心Y坐标
 7      * @param r1    圆形1的半径
 8      * @param r2    圆形2的半径
 9      * @return
10      */
11     private boolean isCollisionWithCircle(int x1, int y1, int x2, int y2, int r1, int r2) {
12         //Math.sqrt:开平方
13         //Math.pow(double x, double y): X的Y次方
14         if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) <= r1 + r2) {
15             //如果两圆的圆心距小于或等于两圆半径则认为发生碰撞
16             return true;
17         }
18         return false;
19     }
复制代码

 

3、多矩形判断

  这时我们就要封装多个矩形来一一判断是否有碰撞。

复制代码
 1 //Rect 类中的四个属性  top bottom left right
 2     //分别表示这个矩形的          上       下            左          右
 3     public boolean isCollsionWithRect(Rect[] rectArray, Rect[] rect2Array) {
 4         Rect rect = null;
 5         Rect rect2 = null;
 6         for (int i = 0; i < rectArray.length; i++) {
 7             //依次取出第一个矩形数组的每个矩形实例
 8             rect = rectArray[i];
 9             //获取到第一个矩形数组中每个矩形元素的属性值
10             int x1 = rect.left + this.rectX1;
11             int y1 = rect.top + this.rectY1;
12             int w1 = rect.right - rect.left;
13             int h1 = rect.bottom - rect.top;
14             for (int j = 0; j < rect2Array.length; j++) {
15                 //依次取出第二个矩形数组的每个矩形实例
16                 rect2 = rect2Array[j];
17                 //获取到第二个矩形数组中每个矩形元素的属性值
18                 int x2 = rect2.left + this.rectX2;
19                 int y2 = rect2.top + this.rectY2;
20                 int w2 = rect2.right - rect2.left;
21                 int h2 = rect2.bottom - rect2.top;
22                 //进行循环遍历两个矩形碰撞数组所有元素之间的位置关系
23                 if (x1 >= x2 && x1 >= x2 + w2) {
24                 } else if (x1 <= x2 && x1 + w1 <= x2) {
25                 } else if (y1 >= y2 && y1 >= y2 + h2) {
26                 } else if (y1 <= y2 && y1 + h1 <= y2) {
27                 } else {
28                     //只要有一个碰撞矩形数组与另一碰撞矩形数组发生碰撞则认为碰撞
29                     return true;
30                 }
31             }
32         }
33         return false;
34     }
复制代码

 

 

 

  

  

========个人网站:http://chendd.com/ 文章很多是上面搬过来的,以后都在个人网站上更新,有兴趣的可以移步☺========
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页