H5中優化碰撞檢測

微信端口的小遊戲相信你們已經作了不少,
相似於碰撞檢測這種也是數不勝數.由於障礙物和主角都是圖片,也就意味着碰撞檢測其實是兩個矩形直接是否有交叉的判斷.包括phaser這樣的框架也是這樣子作的.
固然這種方法也無可厚非.canvas

然而, 惟一的問題是若是素材(障礙物和主角)並不能鋪滿整個矩形的話一旦程序檢查到碰撞而實際上兩個素材並無真正意義上的接觸就會略顯尷尬,
以下面這個圖所示:微信

圖片描述

爲了方便演示和對比起來更直觀, 我給兩個png圖片加了背景, 若是是簡單的矩形相交判斷這個時候判斷了碰撞就會很尷尬...框架

因此, 咱們須要稍微高級點兒的辦法來解決, 雖然我數學不好, 可是仍是要考數學來解決:
用判斷矩形的四條邊是否有與多邊形上的邊相交來替代單純的兩個矩形相交.工具

在案例中, 由於個人障礙物都比較小 並且填的比較滿, 因此就不作拆分(如上圖的綠色的血), 主角有棱有角 須要作一下拆分轉換爲多邊形.
在程序中我是取障礙物的座標和主角的座標來作判斷的, 所以, 獲取主角的座標就是首要任務, 最快捷的方法就是借住ps的鋼筆工具, 以下圖所示:性能

圖片描述

用鋼筆工具沿着豬腳的實際圖片區域走一次, 而後把相對座標點記錄下來. 所謂的相對座標點是基於該圖片左上角水平和垂直方向的距離,優化

好比第一個點的座標是x:42, y:8. spa

我作這些小遊戲的思路是 主角和障礙物都在一個canvas上作, 程序先記錄下豬腳的起點座標 而後根據相對座標便可計算出多邊形的每一個點在canvas上的實際座標了. 拿到實際座標後咱們就能夠作公式的運算判斷是否相撞了, 公式以下:code

/**
 *@param {Array} point 障礙物4個點座標的集合
 *@param {String} x 主角的x座標
 *@param {String} x 主角的y座標
 *@param {Array} area 主角偏移座標的集合
 */
function lineJudge(point, x, y, area){
    var p1, p2, p3, p4;
    for(var i = 0; i < 4; i++) {
        p1 = point[i];
        if(3 == i) {
            p2 = point[0]
        }
        else {
            p2 = point[i + 1];
        }
        
        for(var j = 0, lenA = area.length; j < lenA; j++) {
            p3 = [area[j][0] + x, area[j][3] + y];
            if(j == lenA - 1) {
                p4 = [area[0][0] + x, area[0][4] + y];
            }
            else {
                p4 = [area[j + 1][0] + x, area[j + 1][5] + y];
            }
            
            if('boolean' != typeof _getIntersectionPoint(p1, p2, p3, p4)) return true;
        }
    }
    return false;
}

function _getIntersectionPoint(a, b, c, d){
     // 三角形abc 面積的2倍  
    var area_abc = (a[0] - c[0]) * (b[1] - c[1]) - (a[1] - c[1]) * (b[0] - c[0]);  
  
    // 三角形abd 面積的2倍  
    var area_abd = (a[0] - d[0]) * (b[1] - d[1]) - (a[1] - d[1]) * (b[0] - d[0]);   
  
    // 面積符號相同則兩點在線段同側,不相交 (對點在線段上的狀況,本例看成不相交處理);  
    if ( area_abc*area_abd>=0 ) {  
        return false;  
    }  
  
    // 三角形cda 面積的2倍  
    var area_cda = (c[0] - a[0]) * (d[1] - a[1]) - (c[1] - a[1]) * (d[0] - a[0]);  
    // 三角形cdb 面積的2倍  
    // 注意: 這裏有一個小優化.不須要再用公式計算面積,而是經過已知的三個面積加減得出.  
    var area_cdb = area_cda + area_abc - area_abd ;  
    if (  area_cda * area_cdb >= 0 ) {  
        return false;  
    }  
  
    //計算交點座標  
    var t = area_cda / ( area_abd- area_abc );  
    var dx= t*(b[0] - a[0]),  
        dy= t*(b[1] - a[1]);  
    return { x: a[0] + dx , y: a[1] + dy };  
}

鑑於手機上性能有限, 能夠先用兩個矩形相交來簡單判斷一下, 只有兩個矩形相交的狀況下再作線是否和多邊形上邊相交的判斷.blog

最後, 附上項目高清二維碼, 歡迎你們體驗:遊戲

圖片描述

相關文章
相關標籤/搜索