JS/HTML5游戏碰撞检测包围盒检测算法常用算法详解【矩形案例】
本文通过一个实例描述了JS/HTML5游戏中常用的碰撞检测包围盒检测算法。分享给大家参考,如下:
矩形包围盒,顾名思义就是用一个矩形来包围图像,而矩形的大小最好是刚好包围图像。这个边框最适合的场景是对象的形状刚好接近矩形。
在具体的应用中,有两种常见的方法来描述矩形边界框。
一:用最小和最大顶点法描述AABB包围盒
在上图中,最小和最大顶点方法用于描述边界框信息。由于Y轴在屏幕坐标系中向下延伸,只需要保持矩形中的最小和最大坐标,即矩形左上角和右下角的顶点,其他点在这两点的范围内。
在这种情况下,只需要比较两个矩形顶点的坐标来判断它们是否碰撞。假设矩形A用(x1,y1)表示左上角,用(x2,y2)表示右下角,矩形B用(x3,y3)表示左上角,用(x4,y4)表示右下角,则满足以下条件,表示没有碰撞;否则,没有碰撞。
无碰撞:x1x4或x2x3。无碰撞:y1y4或y2y3。关键代码如下:
函数hittest (source,target) {/*源对象和目标对象都包含x,y和宽度,高度*/return!(((source . y source . r)(target . y))| |(source . y(target . y target . r))|((source . x source . r)target . x)| |(source . x(target . x target . r)));}DEMO代码:
!DOCTYPE html html lang=' en ' head meta name=' viewport ' content=' width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0 ' meta charset=' UTF-8 ' title盒包围碰撞算法-矩形/title style # stage {边框: 1px纯色浅灰色;}/样式/标题dyh 1是否碰撞:span class='hitTest '否/span/h1 canvas id=' stage '/canvas/body脚本窗口。onload=function(){ var stage=document。queryselector(' stage '),CTX=stage。get context(' 2d ');舞台宽度=400舞台高度=400;//栅格线条函数drawGrid(上下文、颜色、stepx、stepy){ context。strokestyle=colorcontext.lineWidth=0.5对于(var i=stepx 0.5I上下文。帆布。宽度;I=stepx){ context。begin path();context.moveTo(i,0);context.lineTo(i,context。帆布。高度);语境。笔画();} for(var I=stepy 0.5;一.背景。帆布。身高;I=stepy){ context。begin path();context.moveTo(0,I);语境。行到(上下文。帆布。宽度,I);语境。笔画();} } var rect={ x : stage。宽度/2-20,y: stage.height/2 - 20,r: 40,c: 'red' },rect=[];直肠。推送(rect);for(var I=0;i 10i ) { var trace={ x: 40 * i,y: 40 * i,r: 40,c : ' blue ' };直肠。推送(跟踪);}函数创建矩形(x,y,r,c){ CTX。begin path();CTX。FillStyle=c;ctx.rect(x,y,r,r);CTX。fill();}文档。onkey down=function(event){ var e=event | | window。事件| |参数。打电话的人。打电话的人。参数[0];//根据地图数组碰撞将测开关(例如键码){ case 37:控制台。日志('左');if (rects[0]).x 0) { rects[0].x-=2;} breakcase 38:控制台。日志(“顶部”);if (rects[0]).y ^ 0){ rects[0].y-=2;}休息案例39:控制台。日志('右');if (rects[0]).x stage.width) { rects[0].x=2;} breakcase 40:控制台。原木(“底部”);if (rects[0]).y stage.height) { rects[0].y=2;} breakdefault:返回false } }stage.addEventListener('click ',function(event){ var x=event。clientx-stage。getboundingclientrect().向左;var y=事件。客户阶段。getboundingclientrect().顶部;rects[0].x=x方向[0]。r/2;rects[0].y=y方向[0]。r/2;});函数hitTest(源,目标){ /*源物体和目标物体都包含x,y以及宽度、高度*/返回!(((来源。y源。(r)目标。y))| |(来源。y(目标。y目标。r))|((来源。x源。r)目标。x)| |(来源。x(目标。x目标。r)));}函数更新(){ CTX。global AlPha=1;ctx.clearRect(0,0,400,400);drawGrid(ctx,'浅灰色',40,40);document.querySelector(' .hitTest ').innerHTML='否;for (var i=1,len=rects.length我透镜;i ) { createRect(rects[i]).x,rects[i].y,rects[i].r,rects[i].c);var flag=hitTest(rects[0],rects[I]);if(flag){ document。' queryselector '。hitTest ').innerHTML='是;CTX . global alpha=0.5 } } createRect(rects[0]).x,rects[0].y,rects[0].r,rects[0].c);requestAnimationFrame(更新);} update();};/script/html这里使用在线HTML/CSS/JavaScript代码运行工具:http://工具。JB 51。net/code/HTMljsrun测试上述代码运行效果如下:
二:采用点和半径描述AABB包围盒
在上图中,中心点和两个轴的半径用于描述边界框信息。假设有两个矩形A和B,矩形A的中心坐标为A(x1,y1),宽度和高度为rx1,ry1,B(x2,y2),B(x2,y2),宽度和高度。
如果两个矩形在X方向的距离小于两个矩形宽度和的一半,Y方向的距离小于两个矩形高度和的一半,则意味着两个矩形重叠,即发生碰撞,公式如下:
x方向满足:|x2-x1|=rx1 rx2,y方向满足:|y2-y1|=ry1 ry2
当然,这种形式也可以转化为微积分的第一种形式。这两种方法在第一种中显然更有效。毕竟,需要使用第二种算法
Math.abs获取绝对值,第一个简单使用坐标比较。
上述矩形边界框也称为AABB(轴对齐)边界框。与轴对齐的边界框中矩形的四条边分别平行于坐标轴,这实际上意味着矩形没有旋转。使用轴对齐包围盒检测算法简单高效,其精度能够满足大多数条件,在实际应用中更具优势。
如果您感兴趣,可以搜索OBB(定向布线)边界框。
Github地址:https://github.com/krapnikkk/JS-gameMathematics
更多对JavaScript相关内容感兴趣的读者可以查看本网站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》和0103010
希望本文对JavaScript编程有所帮助。
版权声明:JS/HTML5游戏碰撞检测包围盒检测算法常用算法详解【矩形案例】是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。