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

最后, 附上项目高清二维码, 欢迎你们体验:游戏

图片描述

相关文章
相关标签/搜索