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

2023-07-19 21:16:00

系列文章目录

第一章 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>

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自动出现并移动、人物动画动作、多地图切换、装备仓库、装备效果等。例如:推箱子、走迷宫、副本游戏、熊猫吃竹子等。

更多推荐

全面解析缓存应用经典问题

1、前言随着互联网从简单的单向浏览请求,发展为基于用户个性信息的定制化以及社交化的请求,这要求产品需要做到以用户和关系为基础,对海量数据进行分析和计算。对于后端服务来说,意味着用户的每次请求都需要查询用户的个人信息和大量的关系信息,此外大部分场景还需要对上述信息进行聚合、过滤、排序,最终才能返回给用户。CPU是信息处理

接口自动化测试完整版(文档+视频)

1.什么是接口测试顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主要分为功能测试,性能测试,稳定性测试,安全性测试等。在分层测试的“金字塔”模型中

QT windows dpi变化导致的界面异常处理

问题:已经在UI界面中利用布局设计好界面,但是运行程序后显示的界面出现错乱,而且在做出一些修改后重新构建,运行时界面无变化。目录一、解决UI设计界面与运行时显示界面不一致的问题1、导致该现象的原因有:显示屏分辨率过高2、使用布局和设置控件sizePolicy二、解决修改界面后重构,运行无变化的问题一、解决UI设计界面与

Spring | Spring监听器使用与入门

引言在复杂的软件开发环境中,组件之间的通信和信息交流显得尤为重要。Spring框架,作为Java世界中最受欢迎的开发框架之一,提供了一种强大的事件监听器模型,使得组件间的通信变得更加灵活和解耦。本文主要探讨Spring事件监听器的原理、使用方法及其在实际开发中的应用,希望为广大开发者提供实用的参考。1.1Spring事

2023年中国研究生数学建模竞赛赛题浅析

为了更好的帮助大家第一天选题,这里首先为大家带来各个赛题的赛题浅析,分析对应赛题之后做题阶段可能会遇到的各种难点。稍后会带来D题的详细解析思路,以及相关的其他版本解题思路成品论文等资料。赛题难度评估:A、B>C>E、F>D选题人数评估:D>E、F>C>A、BA题WLAN网络信道接入机制建模B题DFT类矩阵的整数分解逼近

【Java 并发编程】CopyOnWriterArrayList 详解

CopyOnWriterArrayList详解1.ArrayList1.1ArrayList和LinkedList的区别1.2ArrayList如何保证线程安全2.CopyOnWriteArrayList原理3.CopyOnWriteArrayList的优缺点3.1优点3.2缺点4.源码分析4.1两个成员变量4.2构造

通过篡改cred结构体实现提权利用

前言在之前的HeapOverflow文章中,作者还构造了任意地址读写的操作,使用了任意地址读写去进行提权,还挺有意思的,记录一下如何利用任意地址读写进行提权。作者利用任意地址读写分别改写modprobe_path以及cred结构体去实现提权的操作,由于改写modprobe_path的方法之前已经研究过了,因此现在详细记

【Qt图形视图框架】QGraphicsScene分析

QGraphicsScene分析描述注意使用示例属性方法成员方法(较重要的)公共槽函数:信号:事件描述QGraphicsScene类提供了一个用于管理大量2D图形项的表面。该类充当QGraphicsItems的容器。它与QGraphicsView一起用于在2D表面上可视化图形项,如线条、矩形、文本,甚至自定义项。QGr

“undefined reference to XXX“问题总结

"undefinedreferencetoXXX"问题总结引言我们在Linux下用C/C++工作的时候,经常会遇到"undefinedreferencetoXXX"的问题,直白地说就是在链接(从.cpp源代码到可执行的ELF文件,要经过预处理->编译->链接三个阶段,此时预处理和编译已经通过了)的时候,链接器找不到XX

【中秋国庆】旅行公众号文章排版素材大全

中秋国庆节长假即将来临,你是否已经做好了旅行计划?在这个举国同庆的时刻,何不走出家门,去感受大自然的壮美、领略历史的厚重以及品尝地道的美食呢?随着假期的临近,各大公众号纷纷推出了相关文章,为节日的氛围增色添彩。今天小编将为宝子们分享一些旅行公众号文章排版素材,帮助你在这个假期里,呈现出一篇富有诗意和浪漫的旅行日记。在排

NSDT孪生场景编辑器系统介绍

一、产品背景数字孪生的建设流程涉及建模、美术、程序、仿真等多种人才的协同作业,人力要求高,实施成本高,建设周期长。如何让小型团队甚至一个人就可以完成数字孪生的开发,是数字孪生工具链要解决的重要问题。考虑到数字孪生复杂的生产流程,一个面向小型团队的数字孪生开发工具应该考虑以下问题:NSDT编辑器的出现很好解决了以上问题,

热文推荐