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 相关文章推荐
判断客户端浏览器是否安装了Flash插件的多种方法
Aug 11 Javascript
浅析js中的浮点型运算问题
Jan 06 Javascript
基于jQuery的图片不完全按比例自动缩小
Jul 11 Javascript
JavaScript将数组转换成CSV格式的方法
Mar 19 Javascript
jQuery判断指定id的对象是否存在的方法
May 22 Javascript
JavaScript 对象深入学习总结(经典)
Sep 29 Javascript
JSONObject使用方法详解
Dec 17 Javascript
基于javascript实现checkbox复选框实例代码
Jan 28 Javascript
sencha ext js 6 快速入门(必看)
Jun 01 Javascript
jQuery EasyUI提交表单验证
Jul 19 Javascript
使用vue与jquery实时监听用户输入状态的操作代码
Sep 19 jQuery
微信小程序实现多选框全选与反全选及购物车中删除选中的商品功能
Dec 17 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
咖啡的化学
2021/03/03 咖啡文化
PHP Smarty生成EXCEL文档的代码
2008/08/23 PHP
php实现utf-8和GB2312编码相互转换函数代码
2013/02/07 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
2015/08/18 PHP
php数据访问之查询关键字
2016/05/09 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
php打乱数组二维数组多维数组的简单实例
2016/06/17 PHP
php适配器模式简单应用示例
2019/10/23 PHP
javascript 模拟坦克大战游戏(html5版)附源码下载
2014/04/08 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
jQuery基于muipicker实现仿ios时间选择
2016/02/22 Javascript
JavaScript lodash常见用法系列小结
2016/08/24 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
2016/09/04 Javascript
Bootstrap select多选下拉框实现代码
2016/12/23 Javascript
微信小程序开发(一) 微信登录流程详解
2017/01/11 Javascript
JS完成画圆圈的小球
2017/03/07 Javascript
基于JavaScript实现验证码功能
2017/04/01 Javascript
javascript+html5+css3自定义提示窗口
2017/06/21 Javascript
优雅的将ElementUI表格变身成树形表格的方法步骤
2019/04/11 Javascript
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
JavaScript setInterval()与setTimeout()计时器
2019/12/27 Javascript
JavaScript中的惰性载入函数及优势
2020/02/18 Javascript
详解Python3中的Sequence type的使用
2015/08/01 Python
numpy库与pandas库axis=0,axis= 1轴的用法详解
2019/05/27 Python
详解Anconda环境下载python包的教程(图形界面+命令行+pycharm安装)
2019/11/11 Python
解决django框架model中外键不落实到数据库问题
2020/05/20 Python
利用Python实现自动扫雷小脚本
2020/12/17 Python
澳大利亚家庭花园和DIY工具网店:VidaXL
2019/05/03 全球购物
国际商务系学生个人的自我评价
2013/11/26 职场文书
林肯就职演讲稿
2014/05/19 职场文书
大三学生学年自我鉴定
2014/09/12 职场文书
专升本学生毕业自我鉴定
2014/10/04 职场文书
华山导游词
2015/02/03 职场文书
撤诉申请书法院范本
2015/05/18 职场文书
导游词之潮音寺
2019/09/26 职场文书