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 相关文章推荐
JavaScript对象、属性、事件手册集合方便查询
Jul 04 Javascript
JavaScript 事件入门知识
Apr 13 Javascript
javascript实现在指定元素中垂直水平居中
Sep 13 Javascript
如何根据百度地图计算出两地之间的驾驶距离(两种语言js和C#)
Oct 29 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
Mar 25 Javascript
jquery编写Tab选项卡滚动导航切换特效
Jul 17 Javascript
jquery实现全选功能效果的实现代码
May 05 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
Sep 06 Javascript
js中的面向对象入门
Mar 06 Javascript
使用Phantomjs和Node完成网页的截屏快照的方法
Jul 16 Javascript
JS实现密码框效果
Sep 10 Javascript
记一次vue跨域的解决
Oct 21 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
索尼ICF-SW100收音机评测
2021/03/02 无线电
如何从一个php文件向另一个地址post数据,不用表单和隐藏的变量的
2007/03/06 PHP
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
2012/10/05 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
2014/10/24 PHP
php验证码生成代码
2015/11/11 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
Laravel中log无法写入问题的解决
2017/06/17 PHP
PHP扩展类型及安装方式解析
2020/04/27 PHP
jQuery查询数据返回object和字符串影响原因是什么
2013/08/09 Javascript
js有序数组的连接问题
2013/10/01 Javascript
javascript计时器事件使用详解
2014/01/07 Javascript
js中把JSON字符串转换成JSON对象最好的方法
2014/03/21 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
2014/05/14 Javascript
jquery实现加载进度条提示效果
2015/11/23 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
JavaScript实现随机点名小程序
2020/10/29 Javascript
[03:00]DOTA2-DPC中国联赛1月18日Recap集锦
2021/03/11 DOTA
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
利用Python如何生成随机密码
2016/04/20 Python
对比Python中__getattr__和 __getattribute__获取属性的用法
2016/06/21 Python
django的分页器Paginator 从django中导入类
2019/07/25 Python
python实现邮件自动发送
2019/08/10 Python
Django中密码的加密、验密、解密操作
2019/12/19 Python
加拿大品牌鞋包连锁店:Little Burgundy
2021/02/28 全球购物
科颜氏印度官网:Kiehl’s印度
2021/02/20 全球购物
火山动力Java笔试题
2014/06/26 面试题
俄语专业职业生涯规划
2014/02/26 职场文书
六五普法规划实施方案
2014/03/21 职场文书
田径运动会开幕式及主持词
2014/03/28 职场文书
信息技术课后反思
2014/04/27 职场文书
幼儿园秋季开学寄语
2014/08/02 职场文书
争先创优活动总结
2014/08/27 职场文书
党员教师群众路线对照检查材料思想汇报
2014/09/29 职场文书
Vue的生命周期一起来看看
2022/02/24 Vue.js