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 相关文章推荐
使用jquery mobile做幻灯播放效果实现步骤
Jan 04 Javascript
一些老手都不一定知道的JavaScript技巧
May 06 Javascript
jQuery实用函数用法总结
Aug 29 Javascript
JavaScript函数详解
Nov 17 Javascript
JavaScript获取页面上被选中文字的方法技巧
Mar 13 Javascript
js跨域请求数据的3种常用的方法
Dec 01 Javascript
动态JavaScript所造成一些你不知道的危害
Sep 25 Javascript
Bootstrap基本插件学习笔记之Tooltip提示工具(18)
Dec 08 Javascript
浅述节点的创建及常见功能的实现
Dec 15 Javascript
js实现三级联动效果(简单易懂)
Mar 27 Javascript
vue引入jq插件的实例讲解
Sep 12 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
Nov 03 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
php实现过滤表单提交中html标签的方法
2014/10/17 PHP
laravel 获取当前url的别名方法
2019/10/11 PHP
JS 巧妙获取剪贴板数据 Excel数据的粘贴
2009/07/09 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
微信小程序 icon组件详细及实例代码
2016/10/25 Javascript
Bootstrap 手风琴菜单的实现代码
2017/01/20 Javascript
jQuery实现简单的计时器功能实例分析
2017/08/29 jQuery
10行代码实现微信小程序滑动tab切换
2018/12/28 Javascript
javascriptvoid(0)含义以及与&quot;#&quot;的区别讲解
2019/01/19 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
2019/08/22 Javascript
解决layer图标icon不加载的问题
2019/09/04 Javascript
JavaScript中的this妙用实例分析
2020/05/09 Javascript
jQuery弹框插件使用方法详解
2020/05/26 jQuery
原生JavaScript写出Tabs标签页的实例代码
2020/07/20 Javascript
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
2017/05/03 Python
Python验证文件是否可读写代码分享
2017/12/11 Python
python+opencv轮廓检测代码解析
2018/01/05 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
2018/02/03 Python
python集合比较(交集,并集,差集)方法详解
2018/09/13 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
python全局变量引用与修改过程解析
2020/01/07 Python
如何使用Python发送HTML格式的邮件
2020/02/11 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
Python 利用argparse模块实现脚本命令行参数解析
2020/12/28 Python
python regex库实例用法总结
2021/01/03 Python
CSS实现圆形放大镜狙击镜效果 只有圆圈里的放大
2012/12/10 HTML / CSS
兰芝美国网上商城:购买LANEIGE睡眠面膜等
2017/06/30 全球购物
MAC彩妆英国官网:M·A·C UK
2018/05/30 全球购物
美国饼干礼物和美食甜点购买网站:Cheryl’s
2020/05/28 全球购物
大型演出策划方案
2014/05/28 职场文书
高校师德师风自我剖析材料
2014/09/29 职场文书
史上最牛辞职信
2015/05/13 职场文书
毕业设计致谢语
2015/05/14 职场文书
PHP新手指南
2021/04/01 PHP
python源码剖析之PyObject详解
2021/05/18 Python
详解Java实践之建造者模式
2021/06/18 Java/Android