资讯专栏INFORMATION COLUMN

H5中优化碰撞检测

苏丹 / 1672人阅读

摘要:微信端口的小游戏相信大家已经做了很多类似于碰撞检测这种也是数不胜数因为障碍物和主角都是图片也就意味着碰撞检测实际上是两个矩形直接是否有交叉的判断包括这样的框架也是这样子做的当然这种方法也无可厚非然而唯一的问题是如果素材障碍物和主角并不能铺满

微信端口的小游戏相信大家已经做了很多,
类似于碰撞检测这种也是数不胜数.因为障碍物和主角都是图片,也就意味着碰撞检测实际上是两个矩形直接是否有交叉的判断.包括phaser这样的框架也是这样子做的.
当然这种方法也无可厚非.

然而, 唯一的问题是如果素材(障碍物和主角)并不能铺满整个矩形的话一旦程序检查到碰撞而实际上两个素材并没有真正意义上的接触就会略显尴尬,
如下面这个图所示:

为了方便演示和对比起来更直观, 我给两个png图片加了背景, 如果是简单的矩形相交判断这个时候判断了碰撞就会很尴尬...

所以, 我们需要稍微高级点儿的办法来解决, 虽然我数学很差, 但是还是要考数学来解决:
用判断矩形的四条边是否有与多边形上的边相交来替代单纯的两个矩形相交.

在案例中, 因为我的障碍物都比较小 而且填的比较满, 所以就不做拆分(如上图的绿色的血), 主角有棱有角 需要做一下拆分转换为多边形.
在程序中我是取障碍物的坐标和主角的坐标来做判断的, 因此, 获取主角的坐标就是首要任务, 最快捷的方法就是借住ps的钢笔工具, 如下图所示:

用钢笔工具沿着猪脚的实际图片区域走一次, 然后把相对坐标点记录下来. 所谓的相对坐标点是基于该图片左上角水平和垂直方向的距离,

比如第一个点的坐标是x:42, y:8.

我做这些小游戏的思路是 主角和障碍物都在一个canvas上做, 程序先记录下猪脚的起点坐标 然后根据相对坐标即可计算出多边形的每个点在canvas上的实际坐标了. 拿到实际坐标后我们就可以做公式的运算判断是否相撞了, 公式如下:

/**
 *@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 };  
}

鉴于手机上性能有限, 可以先用两个矩形相交来简单判断一下, 只有两个矩形相交的情况下再做线是否和多边形上边相交的判断.

最后, 附上项目高清二维码, 欢迎大家体验:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91751.html

相关文章

  • 记一次游戏H5开发经验

    摘要:为了实现物体随机出现的效果,让每个物体随机多少秒后开始出现最后一个物体出现完,多少秒后出现结束画面等等,需要理清楚各个定时器的关系,并对其添加语义化良好的标记,及时对未完结的定时器进行清除,防止定时器带来的意想不到的问题。 快到年终的时候做了一个以游戏形式展示的h5活动页,第一次尝试使用js写小游戏,很有趣的过程,很宝贵的经验。 效果图 直接上个效果的gif图,游戏的一小部分效果,录出...

    xingpingz 评论0 收藏0
  • 记一次游戏H5开发经验

    摘要:为了实现物体随机出现的效果,让每个物体随机多少秒后开始出现最后一个物体出现完,多少秒后出现结束画面等等,需要理清楚各个定时器的关系,并对其添加语义化良好的标记,及时对未完结的定时器进行清除,防止定时器带来的意想不到的问题。 快到年终的时候做了一个以游戏形式展示的h5活动页,第一次尝试使用js写小游戏,很有趣的过程,很宝贵的经验。 效果图 直接上个效果的gif图,游戏的一小部分效果,录出...

    GitChat 评论0 收藏0
  • 碰撞检测

    摘要:碰撞检测刚才回答了一个游戏的问答。心血来潮,就想写写碰撞检测,废话不多说,直接怼。矩形和矩形的碰撞检测现有。资料圆形与矩形碰撞检测圆形与旋转矩形碰撞检测属性椭圆碰撞检测 碰撞检测 刚才回答了一个H5游戏的问答。心血来潮,就想写写碰撞检测,废话不多说,直接怼。 矩形和矩形的碰撞检测 现有rect1 = {x:0,y:0,w:5,h:5};rect2 = {x:10,y:10,w:5,h...

    Dogee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<