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的滚动鼠标放大缩小图片效果
Oct 27 Javascript
jQuery实现商品活动倒计时
Oct 16 Javascript
基于bootstrap风格的弹框插件
Dec 28 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
Dec 30 Javascript
JS判断指定dom元素是否在屏幕内的方法实例
Jan 23 Javascript
Jquery根据浏览器窗口改变调整大小的方法
Feb 07 Javascript
Vue单页式应用(Hash模式下)实现微信分享的实例
Jul 21 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
Vue数据双向绑定原理及简单实现方法
May 18 Javascript
JS动态插入脚本和插入引用外部链接脚本的方法
May 21 Javascript
JavaScript中this的全面解析及常见实例
May 14 Javascript
Vue中常用rules校验规则(实例代码)
Nov 14 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中error_log()函数的使用方法
2015/01/20 PHP
基于php实现七牛抓取远程图片
2015/12/01 PHP
Zend Framework自定义Helper类相关注意事项总结
2016/03/14 PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
2017/02/06 PHP
thinkphp 验证码 的使用小结
2017/05/07 PHP
PHP的PDO预定义常量讲解
2019/01/24 PHP
ExtJS 2.2.1的grid控件在ie6中的显示问题
2009/05/04 Javascript
jQuery Flash/MP3/Video多媒体插件
2010/01/18 Javascript
json格式化/压缩工具 Chrome插件扩展版
2010/05/25 Javascript
js显示时间 js显示最后修改时间
2013/01/02 Javascript
深入理解javascript原型链和继承
2014/09/23 Javascript
浅谈jQuery中height与width
2015/07/06 Javascript
NodeJS实现阿里大鱼短信通知发送
2016/01/17 NodeJs
AngularJS基础 ng-options 指令详解
2016/08/02 Javascript
详解React Native开源时间日期选择器组件(react-native-datetime)
2017/09/13 Javascript
详解Angular6学习笔记之主从组件
2018/09/05 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
mock.js实现模拟生成假数据功能示例
2019/01/15 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
2019/04/10 Javascript
JQuery发送ajax请求时中文乱码问题解决
2019/11/14 jQuery
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
如何用itertools解决无序排列组合的问题
2017/05/18 Python
Tensorflow卷积神经网络实例进阶
2018/05/24 Python
python使用RNN实现文本分类
2018/05/24 Python
python中metaclass原理与用法详解
2019/06/25 Python
Python pip 安装与使用(安装、更新、删除)
2019/10/06 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
2019/12/11 Python
在spyder IPython console中,运行代码加入参数的实例
2020/04/20 Python
html5 CSS过度-webkit-transition使用介绍
2013/07/02 HTML / CSS
YSL Beauty加拿大官方商城:圣罗兰美妆加拿大
2017/05/15 全球购物
上班离岗检讨书
2014/01/27 职场文书
股权转让协议书
2014/12/07 职场文书
法院个人总结
2015/03/03 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
2019银行竞聘书
2019/06/21 职场文书
利用python做数据拟合详情
2021/11/17 Python