JavaScript绘制游戏地图并且操控人物移动

 更新时间:2023年10月21日 16:50:48   作者:青花锁  
JavaScript开发小游戏,目标是使用JavaScript绘制简单的二维地图,采用二维数组存储地图信息,使用表格绘制地图,每个td单元格存储数据,使用JavaScript keyPress键盘事件监听WASD键,按键触发时人物做出相应操作,人物下一步碰撞到障碍物,终止人物运动

JavaScript开发小游戏,目标是使用JavaScript绘制简单的二维地图,采用二维数组存储地图信息,使用表格绘制地图,每个td单元格存储数据。使用JavaScript keyPress键盘事件监听WASD键,按键触发时人物做出相应操作。人物下一步碰撞到障碍物,终止人物运动。

一、列计划

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>

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

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

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>

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

<script>
     var row = mapData.length;  //地图的行
     var column = mapData[0].length;  //地图的列
</script>

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 += "<tr>";
          for (var j = 0; j < column; j++) {
            if( mapData[i][j] == 0 ){
              mapHTML += "<td></td>";
            } else if( mapData[i][j] == 1 ){
              mapHTML += '<td><img src="../img/item/stone.png" style="height: 90px; height: 90px; border-radius: 50%;" ></td>';
            } else if( mapData[i][j] == 9 ){
              mapHTML += '<td><img src="../img/item/panda1.png" style="height: 90px; height: 90px; border-radius: 50%;" ></td>';
            }
          }
          mapHTML += "</tr>";
        }
        map.innerHTML = mapHTML;
      }
</script>
<body onload="init()" >

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)">

3、部分效果

尝试走到右上角的位置,初始化位置:1,4,目标值:1,1

尝试走直线,从左走到目标,中途碰到石头障碍就走不动了,此时上下左都有石头障碍,都走不动,只能向右走

向右走1格
向下走2格
向左走2格
向上走一格
向左走一格
向上走一格
抵达目标

总结

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

相关文章

  • js split函数用法总结(从入门到精通)

    js split函数用法总结(从入门到精通)

    js split就是将一字符串以特定的字符分割成数组,数组一般是字符串处理比较常用的处理方法
    2013-03-03
  • js无法获取到html标签的属性的解决方法

    js无法获取到html标签的属性的解决方法

    下面小编就为大家带来一篇js无法获取到html标签的属性的解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • JavaScript迭代器与生成器使用详解

    JavaScript迭代器与生成器使用详解

    迭代器是一个统一的接口,它的作用是使各种数据结构可以被便捷的访问,它是通过一个键为Symbol.iterator的方法来实现,这篇文章主要介绍了ES6 中的迭代器和生成器,需要的朋友可以参考下
    2022-11-11
  • 前端设计师们最常用的JS代码汇总

    前端设计师们最常用的JS代码汇总

    本文给大家整理汇总了一些做前端经常需要用的到JavaScript代码片段,非常的全面,有需要的小伙伴可以参考下
    2016-09-09
  • js实现点击切换和自动播放的轮播图

    js实现点击切换和自动播放的轮播图

    这篇文章主要为大家详细介绍了js实现点击切换和自动播放的轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • JS使用eval解析JSON的注意事项分析

    JS使用eval解析JSON的注意事项分析

    这篇文章主要介绍了JS使用eval解析JSON的注意事项,结合实例形式具体分析了JS解析JSON的技巧与使用evel时的注意事项,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • js函数与php函数的区别实例浅析

    js函数与php函数的区别实例浅析

    这篇文章主要介绍了js函数与php函数的区别,以实例形式较为简单的分析了js函数与php函数语法及应用上的不同点,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • OkHttp踩坑随笔为何 response.body().string() 只能调用一次

    OkHttp踩坑随笔为何 response.body().string() 只能调用一次

    想必大家都用过或接触过 OkHttp,我最近在使用 Okhttp 时,就踩到一个坑,在这儿分享出来,以后大家遇到类似问题时就可以绕过去
    2018-01-01
  • JavaScript编写实现飞机大战

    JavaScript编写实现飞机大战

    这篇文章主要为大家详细介绍了JavaScript编写实现飞机大战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • JS实现随机生成10个手机号的方法示例

    JS实现随机生成10个手机号的方法示例

    这篇文章主要介绍了JS实现随机生成10个手机号的方法,涉及javascript数值运算与随机数操作相关使用技巧,需要的朋友可以参考下
    2018-12-12

最新评论