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


Posted in Javascript onDecember 13, 2018

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

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

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

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

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

关键代码:

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)
   );
  }

完整示例代码:

<!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 {
   border: 1px solid lightgray;
  }
 </style>
</head>
<body>
<h1>是否碰撞:<span class="hitTest">否</span></h1>
<canvas id="stage"></canvas>
</body>
<script>
 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();
 };
</script>
</html>

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

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

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

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

Javascript 相关文章推荐
基于jQuery的图片不完全按比例自动缩小
Jul 11 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
Feb 20 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
Jul 01 Javascript
JavaScript处理解析JSON数据过程详解
Sep 11 Javascript
AngularJS 让人爱不释手的八种功能
Mar 23 Javascript
Vue开发过程中遇到的疑惑知识点总结
Jan 20 Javascript
three.js实现3D视野缩放效果
Nov 16 Javascript
JavaScript面向对象的程序设计(犯迷糊的小羊)
May 27 Javascript
VUE简单的定时器实时刷新的实现方法
Jan 20 Javascript
Vue运用transition实现过渡动画
May 06 Javascript
Vue触发隐藏input file的方法实例详解
Aug 14 Javascript
layer弹出层扩展主题的方法
Sep 11 Javascript
示例vue 的keep-alive缓存功能的实现
Dec 13 #Javascript
Element UI框架中巧用树选择器的实现
Dec 12 #Javascript
vue-cli中安装方法(图文详细步骤)
Dec 12 #Javascript
新版小程序登录授权的方法
Dec 12 #Javascript
加快Vue项目的开发速度的方法
Dec 12 #Javascript
关于自定义Egg.js的请求级别日志详解
Dec 12 #Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
Dec 12 #Javascript
You might like
腾讯微博提示missing parameter errorcode 102 错误的解决方法
2014/12/22 PHP
php目录拷贝实现方法
2015/07/10 PHP
phpinfo() 中 Local Value(局部变量)Master Value(主变量) 的区别
2016/02/03 PHP
PHP检查网站是否宕机的方法示例
2017/07/24 PHP
SUN的《AJAX与J2EE》全文译了
2007/02/23 Javascript
jQuery UI-Draggable 参数集合
2010/01/10 Javascript
js时间戳格式化成日期格式的多种方法
2013/11/11 Javascript
JavaScript获取当前页面上的指定对象示例代码
2014/02/28 Javascript
js简单实现交换Li的值
2014/05/22 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
JS+CSS实现滑动切换tab菜单效果
2015/08/25 Javascript
JS判断字符串变量是否含有某个字串的实现方法
2016/06/03 Javascript
Nodejs 获取时间加手机标识的32位标识实现代码
2017/03/07 NodeJs
微信小程序获取手机网络状态的方法【附源码下载】
2017/12/08 Javascript
Nodejs异步回调之异常处理实例分析
2018/06/22 NodeJs
vue实现条件叠加搜索的解决方法
2019/05/28 Javascript
jQuery cookie的公共方法封装和使用示例
2020/06/01 jQuery
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
Antd的Table组件嵌套Table以及选择框联动操作
2020/10/24 Javascript
手写Vue源码之数据劫持示例详解
2021/01/04 Vue.js
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
Python使用matplotlib绘制余弦的散点图示例
2018/03/14 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
2018/06/14 Python
python中ASCII码和字符的转换方法
2018/07/09 Python
Random 在 Python 中的使用方法
2018/08/09 Python
Python grpc超时机制代码示例
2020/09/14 Python
DC Shoes俄罗斯官网:美国滑板鞋和服饰品牌
2020/08/19 全球购物
应届毕业生的自我鉴定
2013/11/13 职场文书
售后服务科岗位职责范文
2013/11/13 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
工作收入住址证明
2014/10/28 职场文书
公司老总年会致辞
2015/07/30 职场文书
教师病假条范文
2015/08/17 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
CSS3实现的文字弹出特效
2021/04/16 HTML / CSS
使用Bandicam录制鼠标指针并附带点击声音,还可以添加点击动画效果
2022/04/11 数码科技