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 相关文章推荐
LazyLoad 延迟加载(按需加载)
May 31 Javascript
jQuery性能优化28条建议你值得借鉴
Feb 16 Javascript
node.js下LDAP查询实例分享
Sep 30 Javascript
基于JavaScript实现自定义滚动条
Jan 25 Javascript
完美实现js选项卡切换效果(一)
Mar 08 Javascript
JavaScript数组排序reverse()和sort()方法详解
Dec 24 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
Jul 10 Javascript
React SSR样式及SEO的实践
Oct 22 Javascript
jQuery pagination分页示例详解
Oct 23 jQuery
浅谈js中的attributes和Attribute的用法与区别
Jul 16 Javascript
JavaScript实现消消乐的源代码
Jan 12 Javascript
JS的深浅复制详细
Oct 16 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
关于js与php互相传值的介绍
2013/06/25 PHP
解析Win7 XAMPP apache无法启动的问题
2013/06/26 PHP
一个JavaScript继承的实现
2006/10/24 Javascript
javascript正则表达式使用replace()替换手机号的方法
2015/01/19 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
元素绑定click点击事件方法
2015/06/08 Javascript
jQuery实现移动端手机商城购物车功能
2016/09/24 Javascript
js常用DOM方法详解
2017/02/04 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
React Native中Navigator的使用方法示例
2017/10/13 Javascript
微信小程序js文件改变参数并在视图上及时更新【推荐】
2018/06/11 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
2018/09/18 Javascript
jQuery利用FormData上传文件实现批量上传
2018/12/04 jQuery
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
[01:42]DOTA2 – 虚无之灵
2019/08/25 DOTA
python将人民币转换大写的脚本代码
2013/02/10 Python
简单介绍Ruby中的CGI编程
2015/04/10 Python
Python文件夹与文件的相关操作(推荐)
2016/07/25 Python
Python中defaultdict与lambda表达式用法实例小结
2018/04/09 Python
Python获取指定字符前面的所有字符方法
2018/05/02 Python
解决python线程卡死的问题
2019/02/18 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
2019/02/22 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
5款Python程序员高频使用开发工具推荐
2019/04/10 Python
Numpy之reshape()使用详解
2019/12/26 Python
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
Expedia法国:全球最大在线旅游公司
2018/09/30 全球购物
Foot Locker德国官方网站:美国运动服和鞋类零售商
2018/11/01 全球购物
澳大利亚波西米亚风连衣裙在线商店:Fortunate One
2019/04/01 全球购物
Lookfantastic意大利官网:英国知名美妆购物网站
2019/05/31 全球购物
行政部主管岗位职责
2013/12/28 职场文书
信息与工商管理职业规划范文:为梦想而搏击
2014/09/11 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
小学生红领巾广播稿
2015/08/19 职场文书
如何用JavaScipt测网速
2021/05/09 Javascript
阿里云服务器(windows)手动部署FTP站点详细教程
2022/08/05 Servers