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 3D球状导航的文章分类
Jul 06 Javascript
基于jquery插件实现常见的幻灯片效果
Nov 01 Javascript
JQuery EasyUI 数字格式化处理示例
May 05 Javascript
JS实现网页Div层Clone拖拽效果
Sep 26 Javascript
学习JavaScript正则表达式
Nov 13 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
May 25 Javascript
浅谈JS之iframe中的窗口
Sep 13 Javascript
vue实现动态数据绑定
Apr 28 Javascript
vue2利用Bus.js如何实现非父子组件通信详解
Aug 25 Javascript
jQuery实现左右滑动的toggle方法
Mar 03 jQuery
简单介绍react redux的中间件的使用
Apr 06 Javascript
JS实现炫酷雪花飘落效果
Aug 19 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网页游戏学习之Xnova(ogame)源码解读(一)
2014/06/23 PHP
php实现可运算的验证码
2015/11/10 PHP
PHP数组基本用法与知识点总结
2020/06/02 PHP
laravel与thinkphp之间的区别与优缺点
2021/03/02 PHP
JavaScript 全角转半角部分
2009/10/28 Javascript
HTML node相关的一些资料整理
2010/01/01 Javascript
jQuery中live方法的重复绑定说明
2011/10/21 Javascript
jquery实现智能感知连接外网搜索
2013/05/21 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
屏蔽script注入小例子
2013/11/12 Javascript
javascript轻松实现当鼠标移开时已弹出子菜单自动消失
2013/12/29 Javascript
JavaScript解析json格式数据简单示例
2014/12/09 Javascript
JavaScript的instanceof运算符学习教程
2016/06/08 Javascript
js实现可旋转的立方体模型
2016/10/16 Javascript
基于Vue.js实现简单搜索框
2020/03/26 Javascript
AngularJS路由删除#符号解决的办法
2017/09/28 Javascript
jQuery 防止相同的事件快速重复触发方法
2018/02/08 jQuery
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
javascript获取元素的计算样式
2019/05/24 Javascript
详解Vue.js中引入图片路径的几种方式
2019/06/17 Javascript
使用eslint和githooks统一前端风格的技巧
2020/07/29 Javascript
vantUI 获得piker选中值的自定义ID操作
2020/11/04 Javascript
[37:50]VP vs TNC Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
python中关于for循环的碎碎念
2017/06/30 Python
python之从文件读取数据到list的实例讲解
2018/04/19 Python
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
Python对象与引用的介绍
2019/01/24 Python
Python字符串逆序的实现方法【一题多解】
2019/02/18 Python
对Python3使运行暂停的方法详解
2019/02/18 Python
详解Python读取yaml文件多层菜单
2019/03/23 Python
django 通过URL访问上传的文件方法
2019/07/28 Python
意大利大型购物中心:Oliviero.it
2017/10/19 全球购物
后勤工作职责
2013/12/22 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
2014年个人售房协议书
2014/10/30 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书