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 相关文章推荐
innerHTML,outerHTML,innerTEXT三者之间的区别
Jan 28 Javascript
PNG背景在不同浏览器下的应用
Jun 22 Javascript
jQuery取消特定的click事件
Feb 29 Javascript
ES6的新特性概览
Mar 10 Javascript
jquery属性,遍历,HTML操作方法详解
Sep 17 Javascript
Vue中用props给data赋初始值遇到的问题解决
Nov 27 Javascript
Vue实现简单分页器
Dec 29 Javascript
JS数组push、unshift、pop、shift方法的实现与使用方法示例
Apr 29 Javascript
vue Element左侧无限级菜单实现
Jun 10 Javascript
JavaScript实现答题评分功能页面
Jun 24 Javascript
如何vue使用el-table遍历循环表头和表体数据
Apr 26 Vue.js
JS实现页面炫酷的时钟特效示例
Aug 14 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
snoopy 强大的PHP采集类使用实例代码
2010/12/09 PHP
php递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
2014/11/14 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
JavaScript prototype对象的属性说明
2010/03/13 Javascript
javascript发送短信验证码实现代码
2015/11/12 Javascript
Node.js如何自动审核团队的代码
2016/07/20 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
jquery插件uploadify多图上传功能实现代码
2016/08/12 Javascript
JS对HTML表格进行增删改操作
2016/08/22 Javascript
js 单引号替换成双引号,双引号替换成单引号的实现方法
2017/02/16 Javascript
Vue.js 父子组件通信的十种方式
2018/10/30 Javascript
JavaScript学习笔记之数组基本操作示例
2019/01/09 Javascript
JavaScript设计模式之观察者模式实例详解
2019/01/16 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
2020/07/22 Javascript
python发送arp欺骗攻击代码分析
2014/01/16 Python
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
实例说明Python中比较运算符的使用
2015/05/13 Python
Python 中 Meta Classes详解
2016/02/13 Python
Python简单连接MongoDB数据库的方法
2016/03/15 Python
对Python字符串中的换行符和制表符介绍
2018/05/03 Python
Python中asyncio模块的深入讲解
2019/06/10 Python
python matplotlib库绘制散点图例题解析
2019/08/10 Python
利用Python小工具实现3秒钟将视频转换为音频
2019/10/29 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
2020/01/09 Python
Python下使用Trackbar实现绘图板
2020/10/27 Python
python实现PolynomialFeatures多项式的方法
2021/01/06 Python
AmazeUI 输入框组的示例代码
2020/08/14 HTML / CSS
世界上最大的家庭自动化公司:Smarthome
2017/12/20 全球购物
企业出纳岗位职责
2014/03/12 职场文书
某某同志考察材料
2014/05/28 职场文书
特岗教师个人总结
2015/02/10 职场文书
鸡毛信观后感
2015/06/11 职场文书
CSS3 制作的图片滚动效果
2021/04/14 HTML / CSS
python playwright 自动等待和断言详解
2021/11/27 Python