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 相关文章推荐
判断客户端浏览器是否安装了Flash插件的多种方法
Aug 11 Javascript
有趣的JavaScript数组长度问题代码说明
Jan 20 Javascript
jquery xMarquee实现文字水平无缝滚动效果
Apr 29 Javascript
javascript 中that的含义示例介绍
May 14 Javascript
javascript arguments使用示例
Dec 16 Javascript
JS显示下拉列表框内全部元素的方法
Mar 31 Javascript
适用于javascript开发者的Processing.js入门教程
Feb 24 Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
Mar 04 Javascript
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
妙用缓存调用链实现JS方法的重载
Apr 30 Javascript
node+koa2+mysql+bootstrap搭建一个前端论坛
May 06 Javascript
Vue.js样式动态绑定实现小结
Jan 24 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
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
德生PL550的电路分析
2021/03/02 无线电
PHP图片处理之使用imagecopyresampled函数实现图片缩放例子
2014/11/19 PHP
深入分析PHP优化及注意事项
2016/07/04 PHP
php实现URL加密解密的方法
2016/11/17 PHP
禁止直接访问php文件代码分享
2020/05/05 PHP
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
javascript:window.open弹出窗口的位置问题
2014/03/18 Javascript
DOM基础教程之事件对象
2015/01/20 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
异步安全加载javascript文件的方法
2015/07/21 Javascript
seajs学习之模块的依赖加载及模块API的导出
2016/10/20 Javascript
jquery 手势密码插件
2017/03/17 Javascript
ES6新特性之模块Module用法详解
2017/04/01 Javascript
开发Vue树形组件的示例代码
2017/12/21 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
2018/09/13 Javascript
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
2019/03/19 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
2019/09/06 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
Python isinstance判断对象类型
2008/09/06 Python
python解析html开发库pyquery使用方法
2014/02/07 Python
跟老齐学Python之从格式化表达式到方法
2014/09/28 Python
初步讲解Python中的元组概念
2015/05/21 Python
python函数装饰器用法实例详解
2015/06/04 Python
教你用python3根据关键词爬取百度百科的内容
2016/08/18 Python
详解Python import方法引入模块的实例
2017/08/02 Python
Python flask框架post接口调用示例
2019/07/03 Python
利用Python进行图像的加法,图像混合(附代码)
2019/07/14 Python
Python封装成可带参数的EXE安装包实例
2019/08/24 Python
基于Python的自媒体小助手---登录页面的实现代码
2020/06/29 Python
天鹅的故事教学反思
2014/02/04 职场文书
十佳美德少年事迹材料
2014/02/05 职场文书
大学生国庆节65周年演讲稿范文
2014/09/25 职场文书
2015军训通讯稿大全
2015/07/18 职场文书
python opencv旋转图片的使用方法
2021/06/04 Python