首页 > 代码库 > html5游戏-包围盒检测算法

html5游戏-包围盒检测算法

矩形包围盒算法:检测2个矩形是否重叠,在这样情况下要判断2个矩形是否碰撞只需要比较两个矩形顶点的坐标即可。假设矩形A用(x1,y1)表示左上角,(x2,y2)表示右下角,矩形B用(x3,y3)表示左上角,(x4,y4)表示右下角,则满足下列条件则表示没有碰撞,反之则碰撞。
没碰撞:x1>x4或者x2<x3。
没碰撞:y1>y4或者y2<y3

var ABBox = function(tBox1,tBox2){    var x1 = tBox1.x,          y1 = tBox1.y,          x2 = tBox1.x + tBox1.w,          y2 = tBox1.y + tBox1.h,          x3 = tBox2.x,          y3 = tBox2.y,          x4 = tBox2.x + tBox2.w,          y4 = tBox2.y + tBox2.h;     if(x1>x4||x2<x3)return false;     if(y1>y4||y2<y3)return false;     return true;};

 

圆形包围盒算法:检测圆形的碰撞比较容易,假设圆A的坐标(x1,y1),半径是r1,圆B的坐标(x2,y2),半径是r2,则如果满足不等式(y2-y1)2+(x2-x1)2<=(r1+r2)2则表示两个圆发生了碰撞,其实就是圆心之间的距离小于两个圆的半径之和即可,由于计算距离需要用到开方运算,效率较低,所以直接比较距离的平方。

var RBBox = function(tBox){        var dx = x-tBox.x,              dy = y-tBox.y,              dr = r+tBox.r;        return dx*dx+dy*dy<dr*dr; };

 

凸多边形包围盒算法:对于2个多边形来说,检测它们是否相交,我们所要做的是计算两个多边形的每条边在分离轴上的投影的距离。找出每条边形成的向量在轴上投影的最大值和最小值,这样在分离轴上的每个多边形就分别以这两个值形成线段,最后比较这两个线段是否重叠就可以判断这两个多边形是否相交了。

所以在做检测的时候只需要按照以下步骤进行即可。
(1) 产生所有的分离轴,选取一条测试。
(2) 计算图形在该分离轴上的投影。
(3) 检测投影是否相交,如果相交则选取下一条,重复步骤2和步骤3,如果不相交则返回不相交。
(4) 所有分离轴检测完毕,返回相交。

//x,y是多边形中心坐标,pArr是一个顶点数组,点的坐标采用相对中心点坐标,按顺时针存放各顶点       init:function(x,y,pArr)       {           this.pArr = pArr;           this._super(x,y);       },            //转换所有顶点坐标到绝对坐标系中       mapToWorld:function()       {          var p = [];          for(var i=0,len = this.pArr.length;i<len-1;i+=2)          {              p.push(this.pArr[i]+this.x,this.pArr[i+1]+this.y);          }          return p;       },       collided:function(tBox)       {                      var p1 = this.mapToWorld(),               p2 = tBox.mapToWorld();           return MathUtil.isCollide(p1,p2);       },
//判断两个多边形是否相交碰撞,p1,p2用于保存多边形点的数组            isCollide:function(p1,p2){                //定义法向量                var e = {"x":0,"y":0};                var p = p1,                    idx=0,                    len1=p1.length,                    len2=p2.length;                for(var i=0,len = len1+len2;i<len-1;i+=2){                    idx = i;                    //计算两个多边形每条边                    if(i>len1){                        p=p2;                        idx=(i-len1);                    }                    if(i==p.length-2){                        px=p[0]-p[idx];                        py=p[1]-p[idx+1];                    }                    else{                        px = p[idx+2]-p[idx],                        py = p[idx+3]-p[idx+1];                    }                    //得到边的法向量                    e.x = -py;                    e.y = px;                    //计算两个多边形在法向量上的投影                    var pp1 = this.calcProj(e,p1);                    var pp2 = this.calcProj(e,p2);                    //计算两个线段在法向量上距离,如果大于0则可以退出,表示无相交                    if(this.segDist(pp1[0],pp1[1],pp2[0],pp2[1])>0){                        return false;                    }                }                return true;            }
//计算同一个轴上线段的距离s1(min1,max1),s2(min2,max2),如果距离小于0则表示两线段有相交;            segDist:function(min1,max1,min2,max2){                if(min1<min2){                    return min2-max1;                }                else{                    return min1-max2;                }            },

 

html5游戏-包围盒检测算法