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

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

发布时间:2020-10-10 13:42:43

来源:脚本之家

阅读:95

作者:krapnik

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

检测物体碰撞实际上是需要检测物体是否相交,而实际应用中物体的形状大小各异,如果直接对物体的边缘进行碰撞检测,实际计算过程的代价非常高昂。如果物体的数量太多,比如像网络游戏中,通常少则几千用户,多则上万、几十万用户同时在线,而这些碰撞都要通过服务器检测,这样计算的消耗,即使是大型服务器也会崩溃,所以通常不需要十分精确的碰撞检测情况下,使用包围盒算法,即把物体放在一个多边形中,这个多边形就是包围盒。

基于这样一个概念,通常情况下我们就使用了最简单的几种多边形,比如圆形、矩形等。

先来看看如何使用圆形包围盒算法,圆形包围盒算法就是使用圆形作为包围盒将物体包围起来,检测的时候只需要检测两个圆形是否碰撞即可。检测圆形的碰撞比较容易,假设圆 A 的坐标(x1, y1),半径是 r1,圆 B 的坐标(x2, y2),半径是 r2,则如果满足不等式(y2−y1)2+(x2−x1)2≤(r1+r2)2则表示两个圆发生了碰撞,其实就是圆心之间的距离小于两个圆的半径之和即可,由于计算距离需要用到开方运算,效率较低,所以直接比较距离的平方。

f420b4962a21970ac6dbb97928641eee.png

关键代码:

function hitTest( source, target ) {

/* 源物体和目标物体都包含 x, y 以及 width, height */

return !(

Math.pow((source.x - target.x),2) + Math.pow((source.y - target.y),2) > Math.pow((source.r + target.r),2)

);

}

完整示例代码:

盒包围碰撞算法-圆形

#stage {

border: 1px solid lightgray;

}

是否碰撞:

window.onload = function () {

var stage = document.querySelector('#stage'),

ctx = stage.getContext('2d');

stage.width = 400;

stage.height = 400;

document.onkeydown = function (event) {

var e = event || window.event || arguments.callee.caller.arguments[0];

//根据地图数组碰撞将测

switch (e.keyCode) {

case 37:

console.log("Left");

if (balls[0].x > 0) {

balls[0].x -= 2;

}

break;

case 38:

console.log("Top");

if (balls[0].y > 0) {

balls[0].y -= 2;

}

break;

case 39:

console.log("Right");

if (balls[0].x < stage.width) {

balls[0].x += 2;

}

break;

case 40:

console.log("Bottom");

if (balls[0].y < stage.height) {

balls[0].y += 2;

}

break;

default:

return false;

}

};

stage.addEventListener('click', function (event) {

var x = event.clientX - stage.getBoundingClientRect().left;

var y = event.clientY - stage.getBoundingClientRect().top;

balls[0].x = x - balls[0].r/2;

balls[0].y = y - balls[0].r/2;

});

var player = {

x: stage.width / 2 - 20,

y: stage.height / 2 - 20,

r: 40,

c: "red"

},balls = [];

balls.push(player);

for (var i = 0; i < 10; i++) {

var ball = {

x: 60 * i,

y: 60 * i,

r: 40,

c: "blue"

};

balls.push(ball);

}

function createBall(x, y, r, c) {

ctx.beginPath();

ctx.fillStyle = c;

ctx.arc(x, y, r, 0, Math.PI*2);

ctx.fill();

}

function hitTest( source, target ) {

/* 源物体和目标物体都包含 x, y 以及 width, height */

return !(

Math.pow((source.x - target.x),2) + Math.pow((source.y - target.y),2) > Math.pow((source.r + target.r),2)

);

}

function update() {

ctx.globalAlpha=1;

ctx.clearRect(0, 0, 400, 400);

document.querySelector('.hitTest').innerHTML = "否";

for (var i = 1, len = balls.length; i < len; i++) {

createBall(balls[i].x, balls[i].y, balls[i].r, balls[i].c);

var flag = hitTest(balls[0],balls[i]);

if(flag){

document.querySelector('.hitTest').innerHTML = "是";

ctx.globalAlpha=0.5;

}

}

createBall(balls[0].x, balls[0].y, balls[0].r, balls[0].c);

requestAnimationFrame(update);

}

update();

};

这里使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun 测试上述代码运行结果如下:

b700047a6994ce7447ea8735c6436872.gif

github地址:https://github.com/krapnikkk/JS-gameMathematics

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值