• [JavaScript游戏开发] 2D二维地图绘制、人物移动、障碍检测


    系列文章目录

    第一章 2D二维地图绘制、人物移动、障碍检测
    第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示)
    第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测
    第四章 绘制Q版地图、键盘上下左右地图场景切换



    前言

    复习JavaScript 事件有感,心血来潮想做一个2D二维地图绘制、人物移动、障碍检测相关的单页面游戏。
    技术栈:JavaScript、Html、CSS
    环境:chrome浏览器
    编辑器:记事本(Idea)
    在这里插入图片描述


    一、列计划

    1.1、目标

    做一个2D二维地图绘制、人物移动、障碍检测相关的单页面游戏

    1.2、步骤

    • 准备素材(图片):草坪、人物(熊猫)、障碍(石头)
    • 初始化布局(表格),边距设置为0,无边框,设置背景图(草坪)平铺拉满
    • 标记草坪、熊猫、石头的代码
    • 初始化二维地图数据,初始化障碍物围墙,初始化人物位置
    • 计算公共变量二维地图的行、列
    • 合并二维地图数据、人物位置数据,渲染到页面
    • 设置全局键盘事件(在Body上添加),监听wasd按键事件:w(上) s(下) a(左) d(右)
    • 在事件里增加任务移动逻辑、增加边界逻辑
    • 在事件里增加障碍检测逻辑

    二、使用步骤

    2.1、准备素材(图片):草坪、人物(熊猫)、障碍(石头)

    在这里插入图片描述
    在这里插入图片描述

    2.2、初始化布局(表格),边距设置为0,无边框,设置背景图(草坪)平铺拉满

    设置table的ID:map1001
    代表是编号1001的地图

    	<style>
            table { border-collapse: collapse; padding: 0  ; background: url("../img/item/grass.png"); width:100%;
                height:100% ; background-position: center; background-size:cover;  background-repeat: no-repeat;  }
            td { width: 100px; height: 100px; }
            tr { display: block; margin: -5px; }
        style>
        
    <body onload="init()" onkeypress="keypress(event)">
    <table id="map1001">
    table>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3、标记草坪、熊猫、石头的代码

    <script>
    	var empty = 0;   //空地或草坪
    	var stone = 1;   //石头的标记是1
        var panda = 9;   //熊猫的标记是9
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.4、初始化二维地图数据,初始化障碍物围墙,初始化人物位置

    <script>
    	/**
           * 加载地图数据
           * 0 空地/草坪
           * 1 石头
           * 9 熊猫
           * @type {number[]}
           */
          var mapData = [
                    [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1] ,
                    [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1] ,
                    [ 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1] ,
                    [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1] ,
                    [ 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1] ,
                    [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1] ,
                    [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1]
          ]
          
    	  var initPoint = [1,4];   //初始化熊猫的位置是 1,4
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2.5、计算公共变量二维地图的行、列

    <script>
    	 var row = mapData.length;  //地图的行
         var column = mapData[0].length;  //地图的列
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.6、合并二维地图数据、人物位置数据,渲染到页面

    <script>
    	 /**
           * 合并二维地图数据、人物位置数据,渲染到页面
           */
          function init() {
            //二维数组里,去初始化熊猫的位置
            mapData[initPoint[0]][initPoint[1]] = panda
            loadData(mapData);
          }
    	
    	  /**
           *  渲染地图
           * @param mapData
           */
          function loadData(mapData) {
            // 获取地图对象
            var map = document.getElementById("map1001");
    
            //渲染一行八列的数据
            var mapHTML = "";
            for (var i = 0; i < row; i++) {
              mapHTML += "";
              for (var j = 0; j < column; j++) {
                if( mapData[i][j] == 0 ){
                  mapHTML += "";
                } else if( mapData[i][j] == 1 ){
                  mapHTML += '';
                } else if( mapData[i][j] == 9 ){
                  mapHTML += '';
                }
              }
              mapHTML += "";
            }
            map.innerHTML = mapHTML;
          }
    script>
    
    <body onload="init()" >
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2.7、设置全局键盘事件(在Body上添加),监听wasd按键事件:w(上) s(下) a(左) d(右)、在事件里增加任务移动逻辑/增加边界逻辑、在事件里增加障碍检测逻辑

    <script>
    	 /**
           * 监听wasd按键事件:w(上) s(下) a(左) d(右)
           * @param e
           */
          var keypress = function keypress(e){
            var keynum = window.event ? e.keyCode : e.which;
            if( 119 == keynum ) {
                var point = initPoint;
                if( point[0] < row - 1 ) {
                    var xPoint = initPoint[1];
                    var yPoint = initPoint[0] - 1;
                    if( checkStone(yPoint,xPoint) ){
                        console.log("碰撞到石头了,停止动作")
                        return
                    }
                    console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint )
    
                    initPoint = [yPoint,xPoint]
                    operatePanda(point);
                    console.log("向上")
                } else {
                    console.log("超出地图范围了,停止动作")
                }
            } else if( 97 == keynum ) {
              var point = initPoint;
              if( point[1] > 0  ) {
    
    
                var xPoint = initPoint[1] -1;
                var yPoint = initPoint[0];
    
                if( checkStone(yPoint,xPoint) ){
                  console.log("碰撞到石头了,停止动作")
                  return
                }
    
                console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint )
                initPoint = [yPoint,xPoint]
                operatePanda(point);
                console.log("向左")
              } else {
                console.log("超出地图范围了,停止动作")
              }
    
            } else if( 115 == keynum ) {
    
                var point = initPoint;
                if( point[0] < row - 1 ) {
                    var xPoint = initPoint[1];
                    var yPoint = initPoint[0] + 1;
                    if( checkStone(yPoint,xPoint) ){
                        console.log("碰撞到石头了,停止动作")
                        return
                    }
                    console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint )
    
                    initPoint = [yPoint,xPoint]
                    operatePanda(point);
                    console.log("向下")
                } else {
                    console.log("超出地图范围了,停止动作")
                }
    
            } else if( 100 == keynum ) {
    
              var point = initPoint;
              if( point[1] < column -1 ) {
                var xPoint = initPoint[1] + 1;
                var yPoint = initPoint[0];
                if( checkStone(yPoint,xPoint) ){
                  console.log("碰撞到石头了,停止动作")
                  return
                }
                console.log("移动后的位置:x:" + xPoint + " , y:" + yPoint )
    
                initPoint = [yPoint,xPoint]
                operatePanda(point);
                console.log("向右")
              } else {
                console.log("超出地图范围了,停止动作")
              }
            }
          }
    
          /**
           * 障碍检测(可加多个障碍条件)
           * @param yPoint
           * @param xPoint
           * @returns {boolean}
           */
          function checkStone(yPoint , xPoint ) {
              return mapData[yPoint][xPoint] == stone;
          }
    script>
    
    <body onload="init()" onkeypress="keypress(event)">
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    3、部分效果图

    • 尝试走到右上角的位置,初始化位置:1,4,目标值:1,1
      在这里插入图片描述
    • 尝试走直线,从左走到目标,中途碰到石头障碍就走不动了,此时上下左都有石头障碍,都走不动,只能向右走
      在这里插入图片描述
    • 向右走1格
    • 向下走2格
    • 向左走2格
    • 向上走一格
    • 向左走一格
    • 向上走一格
    • 抵达目标 在这里插入图片描述

    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了2D二维地图绘制、人物移动、障碍检测,可以根据此开发出自动寻径避障、多障碍物绘制、NPC自动出现并移动、人物动画动作、多地图切换、装备仓库、装备效果等。例如:推箱子、走迷宫、副本游戏、熊猫吃竹子等。

  • 相关阅读:
    蓝桥杯备赛经验分享---如何拿蓝桥国一?
    Nginx 安装配置和实际使用
    pgpool密码验证失败问题
    【Linux】 yum —— Linux 的软件包管理器
    前端3D规划
    【ROS进阶篇】第三讲 ROS文件系统与分布式通信
    ​企业数据泄露不断,深信服EDR助企业构建数据“安全屋”
    Java面向对象8——抽象类和抽象方法(知识点+使用方法)
    【BAT-表姐御用03MD(ren)命令】文件夹批量创建/命名/改名
    JS中一些判空操作,判null,判undefined操作和简化操作和if操作
  • 原文地址:https://blog.csdn.net/s445320/article/details/131816861