[JavaScript game development] 2D two-dimensional map drawing, character movement, obstacle detection

Series Article Directory

Chapter 1 2D two-dimensional map drawing, character movement, obstacle detection



foreword

After reviewing JavaScript events, I wanted to make a single-page game related to 2D two-dimensional map drawing, character movement, and obstacle detection on a whim.
Technology stack: JavaScript, Html, CSS
Environment: chrome browser
Editor: Notepad (Idea)
insert image description here


1. Column plan

1.1. Goals

Make a single-page game related to 2D two-dimensional map drawing, character movement, and obstacle detection

1.2. Steps

  • Prepare materials (pictures): lawn, people (pandas), obstacles (stones)
  • Initialize the layout (table), set the margin to 0, no border, set the background image (lawn) to be fully tiled
  • Code to mark lawn, panda, stone
  • Initialize the two-dimensional map data, initialize the obstacle wall, and initialize the character position
  • Calculate the rows and columns of the public variable two-dimensional map
  • Merge two-dimensional map data and character position data, and render to the page
  • Set global keyboard events (add on Body), listen to wasd key events: w (up) s (down) a (left) d (right)
  • Add task movement logic and boundary logic to events
  • Add obstacle detection logic to events

2. Use steps

2.1. Prepare materials (pictures): lawn, characters (pandas), obstacles (stones)

insert image description here
insert image description here

2.2. Initialize the layout (table), set the margin to 0, no border, set the background image (lawn) to be fully tiled

Set the ID of the table: map1001
represents the map numbered 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. Codes for marking lawns, pandas, and stones

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

2.4. Initialize the two-dimensional map data, initialize the obstacle wall, and initialize the character position

<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. Calculate the rows and columns of the public variable two-dimensional map

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

2.6. Merge two-dimensional map data and character position data, and render to the page

<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. Set global keyboard events (add on Body), listen to wasd key events: w (up) s (down) a (left) d (right), add task movement logic/add boundary logic to events, add obstacle detection logic to events

<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. Some renderings

  • Try to go to the upper right corner, initial position: 1,4, target value: 1,1
    insert image description here
  • Try to walk in a straight line, walk from the left to the goal, and you will be unable to walk if you encounter stone obstacles on the way. At this time, there are stone obstacles on the up, down, left and right, and you cannot walk, so you can only go to the right
    insert image description here
  • go right 1 space
  • go down 2 squares
  • go left 2 squares
  • go up one space
  • go one square to the left
  • go up one space
  • reach the targetinsert image description here

Summarize

The above is what I want to talk about today. This article only briefly introduces 2D two-dimensional map drawing, character movement, and obstacle detection. Based on this, automatic path finding and obstacle avoidance, multi-obstacle drawing, NPC automatic appearance and movement, character animation actions, multi-map switching, equipment warehouse, equipment effects, etc. can be developed. For example: Sokoban, maze, replica game, panda eating bamboo, etc.

Guess you like

Origin blog.csdn.net/s445320/article/details/131816861