JS/HTML5游戏常用算法之碰撞检测包围盒检测算法详解【矩形情况】

  

本文实例讲述了JS/HTML5游戏常用算法之碰撞检测包围盒检测算法。分享给大家供大家参考,具体如下:

  

矩形包围盒,顾名思义,就是使用一个矩形来包围住图像,矩形的大小以刚好包围住图像为最佳,这种包围盒最适用的场景是刚好物体的形状接近于矩形。

  

在具体的应用中,描述矩形包围盒的的常用方式有以下两种,

  

<强>一:采用最小最大顶点法描述AABB包围盒

  

 JS/HTML5游戏常用算法之碰撞检测包围盒检测算法详解【矩形情况】“> </p>
  <p>上图中使用了最小最大顶点法来描述包围盒信息,由于是在屏幕坐标系中,y轴是向下延伸的,所以只需要保留矩形中坐标的最小值和最大值即可,即矩形的左上角和右下角的顶点,其他的点都在这两个点范围内。</p>
  <p>在这种情况下要判断两个矩形是否碰撞只需要比较两个矩形顶点的坐标即可,假设矩形一个用(x1, y1)表示左上角,(x2, y2)表示右下角,矩形B用(x3, y3)表示左上角,(x4、y4)表示右下角,则满足下列条件则表示没有碰撞,反之则碰撞。</p>
  <ul>
  <李>没碰撞:x1> x4或者x2<x3。</李>
  <李>没碰撞:y1> y4或者y2<y3。</李>
  </ul>
  <p>关键代码如下:</p>
  
  <pre类=   函数hitTest(源、目标){/*源物体和目标物体都包含x, y以及宽度,高度*/返回!   (来源。y +源。r) & lt;(目标。y) | |   (来源。y比;(目标。y +目标。r) | |   (来源。x +源。r) & lt;目标。x) | |   (来源。x比;(目标。x +目标。r))   );   }      之前      

演示代码:

        & lt; !DOCTYPE html>   & lt; html lang=癳n”比;   & lt; head>   & lt;元name=笆哟啊蹦谌?翱矶?设备宽度,初始=1.0,最大范围=1.0,user-scalable=0”的在   & lt;元charset=皍tf - 8”比;   & lt; title>盒包围碰撞算法——矩形& lt;/title>   & lt; style>   #{阶段   边界:1 px固体浅灰色;   }   & lt;/style>   & lt;/head>   & lt; body>   & lt; h2>是否碰撞:& lt;跨类=癶itTest祝辞否& lt;/span> & lt;/h2>   & lt;帆布id=敖锥巍弊4? lt;/canvas>   & lt;/body>   & lt; script>   窗口。onload=function () {   var=document.querySelector阶段(“#阶段”),   ctx=stage.getContext (2 d);   阶段。宽度=400;   阶段。身高=400;//栅格线条   函数drawGrid(上下文,颜色、stepx stepy) {   上下文。strokeStyle=颜色;   上下文。线宽=0.5;   我对(var=stepx + 0.5;我& lt;context.canvas.width;我+=stepx) {   context.beginPath ();   上下文。函数(0);   上下文。画线(我context.canvas.height);   context.stroke ();   }   我对(var=stepy + 0.5;我& lt;context.canvas.height;我+=stepy) {   context.beginPath ();   上下文。函数(0,1);   context.lineTo (context.canvas。宽度,我);   context.stroke ();   }   }   var矩形={   x:阶段。宽/2 - 20,   y:阶段。高度/2 - 20,   接待员:40岁   c:“红色”   },矩形=[];;   rects.push(矩形);   (var=0;我& lt;10;我+ +){   var={痕迹   x: 40 *我,   y: 40 *我,   接待员:40岁   c:“蓝色”   };   rects.push(跟踪);   }   函数createRect (x, y, r, c) {   ctx.beginPath ();   ctx。fillStyle=c;   ctx。矩形(x, y, r, r);   ctx.fill ();   }   文档。onkeydown=函数(事件){   var e=事件| |窗口。事件| | arguments.callee.caller.arguments [0];//根据地图数组碰撞将测   开关(e.keyCode) {   例37:   console.log(“左”);   如果(矩形[0]。x比;0){   矩形[0]。x -=2;   }   打破;   例38:   console.log(“顶级”);   如果(矩形[0]。y比;0){   矩形[0]。y -=2;   }   打破;   例39:   console.log(“正确的”);   如果(矩形[0]。x & lt;stage.width) {   矩形[0]。x +=2;   }   打破;   例40:   console.log(“底部”);   如果(矩形[0]。y & lt;height) {   矩形[0]。y +=2;   }   打破;   默认值:   返回错误;   }   };   阶段。addEventListener(“点击”,函数(事件){   var x=事件。.left clientX stage.getBoundingClientRect ();   var y=事件。直clientY - stage.getBoundingClientRect()上;   矩形[0]。x=x -矩形[0]r/2;   矩形[0]。y=y -矩形[0]r/2;   });   函数hitTest(源、目标){/*源物体和目标物体都包含x, y以及宽度,高度*/返回!   (来源。y +源。r) & lt;(目标。y) | |   (来源。y比;(目标。y +目标。r) | |   (来源。x +源。r) & lt;目标。x) | |   (来源。x比;(目标。x +目标。r))   );   }   函数update () {   ctx。globalAlpha=1;   ctx。clearRect (0, 0, 400, 400);   drawGrid (ctx、浅灰色,40、40);   document.querySelector (“.hitTest”)。innerHTML=胺瘛?   (var i=1, len=rects.length;我& lt;兰;我+ +){   createRect(矩形[我]。x,矩形[我]。y,矩形[我]。r,矩形[我]. c);   var国旗=hitTest(矩形[0],矩形[我]);   如果(国旗){   document.querySelector (“.hitTest”)。innerHTML=笆恰?   ctx。globalAlpha=0.5;   }   }   createRect(矩形[0]。x,矩形[0]。y,矩形[0]。r,矩形[0]. c);   requestAnimationFrame(更新);   }   update ();   };   & lt;/script>   & lt;/html>      

JS/HTML5游戏常用算法之碰撞检测包围盒检测算法详解【矩形情况】