JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解


Posted in Javascript onDecember 12, 2018

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

这种算法经常用于RPG(早期的《最终幻想》、《DQ》、《仙剑奇侠传》)、SLG(《炎龙骑士团》、《超级机器人大战》)、PUZ(《俄罗斯方块》、《宝石谜阵》)类型的游戏。这类游戏中,通常情况下整个地图都是由一些地图块元素组成,在制作的时候首先给制作出地图所需要的最基本的元素进行编号,然后把这些编号的地图块组合起来就可以根据需要形成任意大小的地图。

早期的RPG类型或者SLG类型的游戏可以明显地看出游戏中的地图是由一些小的地图块格子而成,采用这种方式组成地图的好处是节约内存的使用,并且不需要太多的地图元素就可以任意组合成足够大的地图,简单灵活,缺陷就是最后制作出的地图不太美观。但实际上为了便于游戏中的碰撞检测,比如人物碰到NPC或者是碰到不可跨越的障碍等情况,在游戏中实际上还是保存了一张看不见的逻辑层。这个层的大小和地图等大,并且也进行了格子划分,主要目的就是为了碰撞检测,通常我们在游戏中对这个碰撞逻辑层使用一个数组描述信息,使用 1 表示不可以通过,0表示可以通过,假设人物和NPC在游戏中行走,这种情况下我们就很容易检测地图中人物是否碰到了NPC或者障碍物。

var mapArr = [
      1, 0, 0, 1,
      0, 0, 0, 1,
      0, 1, 0, 0,
      1, 0, 0, 1
    ];

代码如下:

<!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>
<canvas id="stage"></canvas>
</body>
<script>
  window.onload = function () {
    var stage = document.querySelector('#stage'),
      ctx = stage.getContext('2d');
    stage.width = 400;
    stage.height = 400;
    var mapArr = [
      1, 0, 0, 1,
      0, 0, 0, 1,
      0, 1, 0, 0,
      1, 0, 0, 1
    ],rectIdx = 5;
    //栅格线条
    function drawGrid(context, color, stepx, stepy) {
      context.strokeStyle = color;
      context.lineWidth = 0.5;
      for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {
        context.beginPath();
        context.moveTo(i, 0);
        context.lineTo(i, context.canvas.height);
        context.stroke();
      }
      for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {
        context.beginPath();
        context.moveTo(0, i);
        context.lineTo(context.canvas.width, i);
        context.stroke();
      }
    }
    function createRect(x, y, r, c) {
      ctx.beginPath();
      ctx.fillStyle = c;
      ctx.rect(x, y, r, r);
      ctx.fill();
    }
    document.onkeydown = function (event) {
      var e = event || window.event || arguments.callee.caller.arguments[0];
      //根据地图数组碰撞将测
      switch (e.keyCode){
        case 37:
          console.log("Left");
          if (rectIdx - 1 >= 0 && (rectIdx - 1) % 4 !== 3 && !mapArr[rectIdx - 1]) {
            rectIdx -= 1;
          }
          break;
        case 38:
          console.log("Top");
          if (rectIdx - 4 >= 0 && !mapArr[rectIdx - 4]) {
            rectIdx -= 4;
          }
          break;
        case 39:
          console.log("Right");
          if ((rectIdx + 1) % 4 !== 0 && !mapArr[rectIdx + 1]) {
            rectIdx += 1;
          }
          break;
        case 40:
          console.log("Bottom");
          if (rectIdx + 4 < mapArr.length && !mapArr[rectIdx + 4]) {
            rectIdx += 4;
          }
          break;
        default:
          return false;


 }
    };
    function update() {
      ctx.clearRect(0, 0, 400, 400);
      drawGrid(ctx, 'lightgray', 100, 100);
      var rect = {
        x: rectIdx % 4 * 100,
        y: rectIdx % 4 === 0 ? rectIdx / 4 * 100 : Math.floor(rectIdx / 4) * 100,
        r: 100,
        c: "blue"
      };
      createRect(rect.x, rect.y, rect.r, rect.c);
      //根据地图数组创建色块
      for (var i = 0, len = mapArr.length; i < len; i++) {
        if (mapArr[i]) {
          createRect(i % 4 * 100, i % 4 === 0 ? i / 4 * 100 : Math.floor(i / 4) * 100, 100, "red");
        }
      }
      requestAnimationFrame(update);
    }
    update();
  };
</script>
</html>

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

JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解

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

采用这种方式判断逻辑极其简单,效率也比较高,但不太精确,如果A物体的大小比格子小很多,则物体行动的时候可能看起来离B物体有些距离就无法行走了,所以做这种类型游戏最好保证格子足够小或者保证人物大小和格子相差不大

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

Javascript 相关文章推荐
javascript Array对象基础知识小结
Nov 16 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
Sep 09 Javascript
js模拟点击以提交表单为例兼容主流浏览器
Nov 29 Javascript
javascript中使用正则计算中文长度的例子
Apr 29 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
Sep 05 Javascript
AngularJs表单验证实例详解
May 30 Javascript
js实现上传文件添加和删除文件选择框
Oct 24 Javascript
js实现右键自定义菜单
Dec 03 Javascript
基于vue-video-player自定义播放器的方法
Mar 21 Javascript
JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例
Dec 14 Javascript
Vue实现根据hash高亮选项卡
May 27 Javascript
基于canvas实现手写签名(vue)
May 21 Javascript
JS/HTML5游戏常用算法之追踪算法实例详解
Dec 12 #Javascript
js使用swiper实现层叠轮播效果实例代码
Dec 12 #Javascript
如何制作一个Node命令行图像识别工具
Dec 12 #Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
Dec 12 #Javascript
ionic使用angularjs表单验证(模板验证)
Dec 12 #Javascript
微信小程序自定义导航教程(兼容各种手机)
Dec 12 #Javascript
express express-session的使用小结
Dec 12 #Javascript
You might like
字符串长度函数strlen和mb_strlen的区别示例介绍
2014/09/09 PHP
php实现用于计算执行时间的类实例
2015/04/18 PHP
jquery dialog键盘事件代码
2010/08/01 Javascript
jquery和js实现对div的隐藏和显示方法
2014/09/26 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
基于jQuery实现Tabs选项卡自定义插件
2016/11/21 Javascript
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
element-ui 关于获取select 的label值方法
2018/08/24 Javascript
对node通过fs模块判断文件是否是文件夹的实例讲解
2019/06/10 Javascript
js设置默认时间跨度过程详解
2019/07/17 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
JavaScript实现栈结构Stack过程详解
2020/03/07 Javascript
[02:44]2014DOTA2 国际邀请赛中国区预选赛 大神红毯秀
2014/05/25 DOTA
python实现的一个火车票转让信息采集器
2014/07/09 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
Numpy数组转置的两种实现方法
2018/04/17 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
Django的性能优化实现解析
2019/07/30 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
Django中ORM找出内容不为空的数据实例
2020/05/20 Python
HTML5中的postMessage API基本使用教程
2016/05/20 HTML / CSS
HTML5视频支持检测(检查浏览器是否支持视频播放)
2013/06/08 HTML / CSS
HTML5手机端弹出遮罩菜单特效代码
2016/01/27 HTML / CSS
HTML5+Canvas+CSS3实现齐天大圣孙悟空腾云驾雾效果
2016/04/26 HTML / CSS
html5本地存储 localStorage操作使用详解
2016/09/20 HTML / CSS
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
EVE LOM英国官网:全世界最好的洁面膏
2017/10/30 全球购物
网络安全类面试题
2015/08/01 面试题
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
房地产活动策划方案
2014/05/14 职场文书
售后服务承诺书怎么写
2014/05/21 职场文书
人大调研汇报材料
2014/08/14 职场文书
刑事撤诉申请书
2015/05/18 职场文书
小组组名及励志口号
2015/12/24 职场文书
《最终幻想14》6.01版本4月5日推出 追加新任务新道具
2022/04/03 其他游戏