JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解

本文实例讲述了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.jb51.net/code/HtmlJsRun测试运行上述代码,可得到如下运行结果:

github地址:https://github.com/krapnikkk/JS-gameMathematics

采用这种方式判断逻辑极其简单,效率也比较高,但不太精确,如果A物体的大小比格子小很多,则物体行动的时候可能看起来离B物体有些距离就无法行走了,所以做这种类型游戏最好保证格子足够小或者保证人物大小和格子相差不大

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • JS图片压缩(pc端和移动端都适用)

    最近在做移动端遇到了一个问题就是:手机拍照后,图片过大如果上传到服务器务必会浪费带宽,最重要的是流量啊别慌,好事儿来了,务必就会有人去研究研究图片的压缩: 鄙人结合前人的经验,结合自己实战,总结出一个方法供大家参考: /** * 图片压缩,默认同比例压缩 * @param {Object} path * pc端传入的路径可以为相对路径,但是在移动端上必须传入的路径是照相图片储存的绝对路径 * @param {Object} obj * obj 对象 有 width, height, qualit

  • js实现碰撞检测特效代码分享

    自己做了碰撞检测的封装,先看下实例demo,在看封装 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>碰撞检测</title> <style type="text/css"> *{ margin: 0; padding: 0; } #divA,#divB{ width: 200px; height: 200px;

  • JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【凹多边形的分离轴检测算法】

    本文实例讲述了JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法.分享给大家供大家参考,具体如下: 概述 分离轴定理是一项用于检测碰撞的算法.其适用范围较广,涵盖检测圆与多边形,多边形与多边形的碰撞:缺点在于无法检测凹多边形的碰撞.本demo使用Js进行算法实现,HTML5 canvas进行渲染. 详细 一.准备工作,熟悉分离轴定理 算法原理 从根本上来讲,分离轴定理(以及其他碰撞算法)的用途就是去检测并判断两个图形之间是否有间隙.分离轴定理中用到的方法使算法本身显得十分独特. 我所听到过分

  • js控制鼠标事件移动及移出效果显示

    鼠标事件的移动及移出效果都可以使用js来自定义,下面有个示例,效果为当事件发生改变时背景颜色也随着改变,适合新手朋友 <style type="text/css"> .style0{ background-color:#FFFF00; } .style1{ background-color:#00FFFF; } </style> </head> <body> <table width="576" height=&

  • javascript制作游戏开发碰撞检测的封装代码

    在JavaScript开发Web游戏时,需要使用到碰撞检测时,为了方便开发,封装了矩形和圆形的两个碰撞检测方式. [附带案例操作捕获一枚] [注意:代码上未做优化处理] 演示图 角色攻击区域碰撞检测.gif 塔防案例.gif 矩形区域碰撞检测 /** * 矩形区域碰撞检测 * Created by Administrator on 14-4-7. * author: marker */ function Rectangle(x, y, _width, _height){ this.x = x;

  • JS实现碰撞检测的方法分析

    本文实例讲述了JS实现碰撞检测的方法.分享给大家供大家参考,具体如下: 一个简单的碰撞检测例子,检测div1是否和div2发生碰撞,当div1碰到div2时,改变div2的颜色,看测试图 看一下分析图: 当div1在div2的上边线(t2)以上的区域活动时,始终碰不上 当div1在div2的右边线(r2)以右的区域活动时,始终碰不上 当div1在div2的下边线(b2)以下的区域活动时,始终碰不上 当div1在div2的左边线(r2)以左的区域活动时,始终碰不上 除了以上四种情况,其他情况表示d

  • JS实现的碰撞检测与周期移动完整示例

    本文实例讲述了JS实现的碰撞检测与周期移动.分享给大家供大家参考,具体如下: <!doctype html> <html> <head> <meta charset="utf-8"> <title>无标题文档</title> <style type="text/css"> #main {width:525px; height:300px; border:3px double blac

  • 原生JS实现的碰撞检测功能示例

    本文实例讲述了原生JS实现的碰撞检测功能.分享给大家供大家参考,具体如下: <!doctype html> <html> <head> <meta charset="utf-8"> <title>www.jb51.net JS碰撞检测</title> <style> div{width:100px; height:100px; } #box{background:red; position:absolu

  • JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解

    本文实例讲述了JS/HTML5游戏常用算法之碰撞检测 像素检测算法.分享给大家供大家参考,具体如下: 使用像素碰撞检测法算是最精确的算法了,当然,带来的代价也是比较明显的,那就是效率上的低下.除非是在极为特殊的情况下,要求使用非常精确的碰撞,否则,一般情况下在游戏中是不建议使用这种算法,特别是在运行效率不太高的HTML5游戏中. 一般来说在使用像素碰撞检测之前会使用AABB矩形包围盒先检测两个精灵是否有碰撞,如果AABB包围盒检测没有碰撞,那一定是没有碰撞到,反之,则不一定,需要进一步进行像素检

  • JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解

    本文实例讲述了JS/HTML5游戏常用算法之碰撞检测 地图格子算法.分享给大家供大家参考,具体如下: 这种算法经常用于RPG(早期的<最终幻想>.<DQ>.<仙剑奇侠传>).SLG(<炎龙骑士团>.<超级机器人大战>).PUZ(<俄罗斯方块>.<宝石谜阵>)类型的游戏.这类游戏中,通常情况下整个地图都是由一些地图块元素组成,在制作的时候首先给制作出地图所需要的最基本的元素进行编号,然后把这些编号的地图块组合起来就可以根据需

  • JS/HTML5游戏常用算法之路径搜索算法 随机迷宫算法详解【普里姆算法】

    本文实例讲述了JS/HTML5游戏常用算法之路径搜索算法 随机迷宫算法.分享给大家供大家参考,具体如下: 路径搜索算法在游戏中非常常见,特别是在 RPG.SLG 中经常用到.在这些游戏中,通过鼠标指定行走目的地,人物或者NPC就会自动行走到目标地点,这就是通过路径搜索或者称为寻路算法来实现的.通俗地说,就是在一张地图中,如何让主角自动行走到指定的地点,如图6-21所示,假设主角在A处,然后玩家在地图中点击B处,要求主角能够从A点自动找寻一条到 B 点的路径,然后自动移动到 B处,要求就这么简单.

  • JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例

    本文实例讲述了JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法.分享给大家供大家参考,具体如下: 原理可参考:https://www.jb51.net/article/152744.htm 完整实例代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-s

  • JS/HTML5游戏常用算法之追踪算法实例详解

    本文实例讲述了JS/HTML5游戏常用算法之追踪算法.分享给大家供大家参考,具体如下: 追踪算法在动作游戏中非常常见,从很早的游戏<吃豆人>到大型的街机机战类游戏,到处可见追踪效果的身影.一个好的追踪算法将会大大提高游戏的可玩性和玩家的兴趣. [简单算法] 先来看一个简单的跟踪算法,如下图所示,假设在canvas坐标系中存在物体A和B,物体A将把B作为追踪目标,物体在二维空间中的运动可以分解为坐标系中X.Y轴的运动,其在X和Y方向的速度决定了物体运行的方向和速率.别忘了,速度是有方向和大小的,

  • java算法之二分查找法的实例详解

    java算法之二分查找法的实例详解 原理 假定查找范围为一个有序数组(如升序排列),要从中查找某一元素,如果该元素在此数组中,则返回其索引,否则返回-1.通过数组长度可取出中间位置元素的索引,将其值与目标值比较,如果中间位置元素值大于目标值,则在左部分进行查找,如果中间位置值小于目标值,则在右部分进行查找,如此循环,直到结束.二分查找算法之所以快是因为它没有遍历数组的每个元素,而仅仅是查找部分元素就能找到目标或确定其不存在,当然前提是查找范围为有序数组. Java的简单实现 package me

  • js中获取URL参数的共用方法getRequest()方法实例详解

    下面通过一段代码给大家介绍js中获取URL参数的共用方法getRequest()方法,具体代码如下所示: getRequest : function() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&am

  • JS中的算法与数据结构之列表(List)实例详解

    本文实例讲述了JS中的算法与数据结构之列表(List).分享给大家供大家参考,具体如下: 前言 前端很少有机会接触到算法,大多都交互性的操作,所以不少前端工程师会抱着这么一种想法:我是做前端的,为什么要学数据结构与算法?没有数据结构与算法,我一样很好的完成工作.实际上,算法是一个宽泛的概念,我们平时写的任何代码都可以成为算法,它是对一个问题的解决方案的准确而完整的描述,是解决一系列问题的清晰指令,它代表着用系统的方法描述解决问题的策略机制.随着现在互联网的飞速发展,前端工程师已不是靠几个选择器操

  • JS中的算法与数据结构之队列(Queue)实例详解

    本文实例讲述了JS中的算法与数据结构之队列(Queue).分享给大家供大家参考,具体如下: 队列(Queue) 我们之前说到了栈,它是一种比较高效的数据结构,遵循 先入后出(LIFO,last-in-first-out) 的原则.而今天我们要讨论的队列,它也是一种特殊的列表,它与栈不同的是, 队列只能在队尾插入元素,在队首删除元素,就像我们平时排队买票一样~ 队列用于存储按顺序排列的数据,遵循 先进先出(FIFO,First-In-First-Out) 的原则,也是计算机常用的一种数据结构,别用

随机推荐