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折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
Jan 22 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
Sep 14 Javascript
jquery ready函数、css函数及text()使用示例
Sep 27 Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
May 12 Javascript
Bootstrap源码解读模态弹出框(11)
Dec 28 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
原生JS实现层叠轮播图
May 17 Javascript
vue刷新和tab切换实例
Feb 11 Javascript
echarts整合多个类似option的方法实例
Jul 10 Javascript
vue动态注册组件实例代码详解
May 30 Javascript
vue 的 solt 子组件过滤过程解析
Sep 07 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
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模板类代码
2008/09/07 PHP
php实现随机生成易于记忆的密码
2015/06/19 PHP
php魔术方法功能与用法实例分析
2016/10/19 PHP
2017年最新PHP经典面试题目汇总(上篇)
2017/03/17 PHP
js innerHTML 的一些问题的解决方法
2008/06/22 Javascript
JS完成代码前最好对其做5件事
2013/04/07 Javascript
form表单action提交的js部分与html部分
2014/01/07 Javascript
Javascript实现Web颜色值转换
2015/02/05 Javascript
原创jQuery弹出层插件分享
2015/04/02 Javascript
JavaScript表格常用操作方法汇总
2015/04/15 Javascript
JavaScript中isPrototypeOf函数作用和使用实例
2015/06/01 Javascript
常用DOM整理
2015/06/16 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
2016/11/03 Javascript
浅谈html转义及防止javascript注入攻击的方法
2016/12/04 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
JavaScript多线程运行库Nexus.js详解
2017/12/22 Javascript
vue加载自定义的js文件方法
2018/03/13 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
jQuery实现的自定义轮播图功能详解
2018/12/28 jQuery
微信jssdk踩坑之签名错误invalid signature
2020/05/19 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
Python和C/C++交互的几种方法总结
2017/05/11 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
python标记语句块使用方法总结
2019/08/05 Python
python3文件复制、延迟文件复制任务的实现方法
2019/09/02 Python
python 基于卡方值分箱算法的实现示例
2020/07/17 Python
基于CSS3特效之动画:animation的应用
2013/05/09 HTML / CSS
使用jquery实现HTML5响应式导航菜单教程
2014/04/02 HTML / CSS
会计专业自我鉴定范文
2013/12/29 职场文书
科级干部考察材料
2014/02/15 职场文书
大专学生求职信
2014/07/04 职场文书
老龄工作先进事迹
2014/08/15 职场文书
先进人物事迹材料
2014/12/29 职场文书
2015年安全生产责任书
2015/01/30 职场文书
2016应届大学生自荐信模板
2016/01/28 职场文书
vue实现滑动解锁功能
2022/03/03 Vue.js