游戲開發基礎--碰撞檢測


  碰撞就是游戲中的元素是否碰到一起,比如打飛機游戲,沒躲避炮彈就算碰撞,要檢測出來,要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     }

 

 

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM