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获取焦点和失去焦点事件代码
Apr 21 Javascript
js判断数据类型如判断是否为数组是否为字符串等等
Jan 15 Javascript
简单的ajax连接库分享(不用jquery的ajax)
Jan 19 Javascript
ExtJS判断IE浏览器类型的方法
Feb 10 Javascript
jQuery实现标题有打字效果的焦点图代码
Nov 16 Javascript
原生js配合cookie制作保存路径的拖拽
Dec 29 Javascript
JavaScript数据存储 Cookie篇
Jul 02 Javascript
原生js实现验证码功能
Mar 16 Javascript
微信小程序之网络请求简单封装实例详解
Jun 28 Javascript
Angularjs 事件指令详细整理
Jul 27 Javascript
ionic选择多张图片上传的示例代码
Oct 10 Javascript
ajax jquery实现页面某一个div的刷新效果
Mar 04 jQuery
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中多维数组按指定value排序的实现代码
2014/08/19 PHP
基于php实现七牛抓取远程图片
2015/12/01 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
Laravel框架中Blade模板的用法示例
2017/08/30 PHP
thinkPHP5框架自定义验证器实现方法分析
2018/06/11 PHP
JS 实现双色表格实现代码
2009/11/24 Javascript
使用jQuery的将桌面应用程序引入浏览器
2010/11/19 Javascript
JavaScript动态插入script的基本思路及实现函数
2013/11/11 Javascript
js如何设置在iframe框架中指定div不显示
2013/12/04 Javascript
nodejs的HTML分析利器node-jquery用法浅析
2016/11/08 NodeJs
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
2017/01/22 Javascript
详解Sea.js中Module.exports和exports的区别
2017/02/12 Javascript
JS实现简单拖拽效果
2017/06/21 Javascript
浅谈JavaScript节流和防抖函数
2020/08/25 Javascript
vue3.0 自适应不同分辨率电脑的操作
2021/02/06 Vue.js
浅谈python数据类型及类型转换
2017/12/18 Python
VSCode下配置python调试运行环境的方法
2018/04/06 Python
Python中如何导入类示例详解
2019/04/17 Python
Python 使用PyQt5 完成选择文件或目录的对话框方法
2019/06/27 Python
Python绘制热力图示例
2019/09/27 Python
python属于跨平台语言码
2020/06/09 Python
css3隔行变换色实现示例
2014/02/19 HTML / CSS
处理textarea中的换行和空格
2019/12/12 HTML / CSS
香港时尚女装购物网站:ZAFUL
2017/07/19 全球购物
Craghoppers德国官网:户外和旅行服装
2020/02/14 全球购物
css animation配合SVG制作能量流动效果
2021/03/24 HTML / CSS
夜大毕业生自我评价分享
2013/11/10 职场文书
大学生职业生涯规划范文
2013/12/31 职场文书
小学秋季运动会报道稿
2014/09/30 职场文书
建党伟业电影观后感
2015/06/01 职场文书
追悼词范文大全
2015/06/23 职场文书
高二化学教学反思
2016/02/22 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书
解析Java中的static关键字
2021/06/14 Java/Android
CSS基础详解
2021/10/16 HTML / CSS