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.ui.dialog 增加“在当前鼠标位置打开”的功能
Nov 24 Javascript
jQuery AJAX回调函数this指向问题
Feb 08 Javascript
JavaScript DOM 学习第二章 编辑文本
Feb 19 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
Sep 02 Javascript
JavaScript中数组slice和splice的对比小结
Sep 22 Javascript
JS去除字符串中空格的方法
Feb 14 Javascript
Vue异步加载about组件
Oct 31 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
node.js基础知识小结
Feb 26 Javascript
vue2.0 根据状态值进行样式的改变展示方法
Mar 13 Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
Aug 19 Javascript
Vue 事件的$event参数=事件的值案例
Jan 29 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解析url的三个示例
2014/01/20 PHP
PHP的Yii框架中行为的定义与绑定方法讲解
2016/03/18 PHP
javascript 学习之旅 (1)
2009/02/05 Javascript
Angularjs基础知识及示例汇总
2015/01/22 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
2016/10/13 Javascript
基于javascript的Form表单验证
2016/12/29 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
基于jQuery实现的单行公告活动轮播效果
2017/08/23 jQuery
如何利用@angular/cli V6.0直接开发PWA应用详解
2018/05/06 Javascript
傻瓜式vuex语法糖kiss-vuex整理
2018/12/21 Javascript
vue插槽slot的理解和使用方法
2019/04/03 Javascript
vue+element实现表格新增、编辑、删除功能
2019/05/28 Javascript
vue读取本地的excel文件并显示在网页上方法示例
2019/05/29 Javascript
javascript导出csv文件(excel)的方法示例
2019/08/25 Javascript
js之切换全屏和退出全屏实现代码实例
2019/09/09 Javascript
JavaScript提升机制Hoisting详解
2019/10/23 Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
2020/07/28 Javascript
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
Ruby元编程基础学习笔记整理
2016/07/02 Python
python编程培训 python培训靠谱吗
2018/01/17 Python
python入门前的第一课 python怎样入门
2018/03/06 Python
python3实现字符串的全排列的方法(无重复字符)
2018/07/07 Python
python单例模式实例解析
2018/08/28 Python
【python】matplotlib动态显示详解
2019/04/11 Python
python re.sub()替换正则的匹配内容方法
2019/07/22 Python
python实现多线程端口扫描
2019/08/31 Python
详解Html5页面实现下载文件(apk、txt等)的三种方式
2018/10/22 HTML / CSS
AJAX检测用户名是否存在的方法
2021/03/24 Javascript
计算机网络毕业生自荐信
2013/10/01 职场文书
会计专业毕业生求职信分享
2014/01/03 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
保险公司客户经理岗位职责
2015/04/09 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
goland设置颜色和字体的操作
2021/05/05 Golang
全网非常详细的pytest配置文件
2022/07/15 Python