javascriptarrayshtml5-canvasgame-developmenttiled

I'm trying to get localisation in multidimensional array which is equal to mouse coord and put the tile id on it but array refresh everytime


I'm new to dev and i'm trying to learn JS doing game on canvas.

This is a Tile Map Editor project

I'm looking to create a multidimensional array with the ID's of the tiles i drew in the canvas. So when i go to export the JSON i can handle the colissions easily on my game.

But I'm stuck, I can detect the mouse position and put my tile id in the right place, but I don't know how to save the information in my array. Every time i try the array does not save the tile id and replaces with the new one.

  //////////////////////////////
 //// TO RESOLVE !!!!! ///////
////////////////////////////
let array = [];

function saveIdexedTiledMap() {
   for (let l = 0; l < canvas.height / 32; l++) {
      array[l] = [];
    for (let c = 0; c < canvas.width / 32; c++) {
      array[l][c] = 0;
    }
  }
  array[mouseCanvasGrids.y / 32][mouseCanvasGrids.x / 32] =
    selectedTile[0].index;

  console.log(array);
}
  

Thanks :D

        ////////////////////////////////////////////////////////////
        /////////// GET INPUT VALUES AND BUTTONS //////////////////
        //////////////////////////////////////////////////////////

        const clearCanvas = document.querySelector("#btn-clearCanvas");
        const exportImage = document.querySelector("#btn-exportImage");

        const form = document.querySelector("#form");
        const submit = document.querySelector("#submit");

        const elems = Array.from(form.elements);

        submit.addEventListener("click", (e) => {
          e.preventDefault();

          elems.forEach((el) => localStorage.setItem(`${el.id}`, `${el.value}`));
        });

        /////////////////////////////////////////////////////////////
        /////////// GET BOTH CANVAS AND VARIABLES //////////////////
        ///////////////////////////////////////////////////////////

        const canvas = document.querySelector("canvas");
        const ctx = canvas.getContext("2d");

        const canvasImg = document.querySelector("#canvasImg");
        const ctxImg = canvasImg.getContext("2d");

        let gridsPosX;
        let gridsPosY;

        let tileSizeW = 32;
        let tileSizeH = 32;

        let gridsColor = "#bad1f5";

        //////////////////////////////////////////////////////////
        /////////// DRAW ON CANVAS TILE GRIDS //////////////////
        ////////////////////////////////////////////////////////

        class DrawGrids {
          constructor(x, y, canvasW, canvasH, tileW, tileH, color) {
            this.x = x;
            this.y = y;
            this.canvasW = canvasW;
            this.canvasH = canvasH;
            this.tileSizeW = tileW;
            this.tileSizeH = tileH;
            this.color = color;
          }

          draw() {
            let tileGridsX;
            let tileGridsY;

            for (let l = 0; l < this.canvasH / this.tileSizeH; l++) {
              for (let c = 0; c < this.canvasW / this.tileSizeW; c++) {
                tileGridsX = c * this.tileSizeW;
                tileGridsY = l * this.tileSizeH;

                const variables = [ctx, ctxImg];

                variables.forEach((el) => {
                  el.strokeStyle = this.color;
                  el.rect(tileGridsX, tileGridsY, this.tileSizeH, this.tileSizeW);
                  el.stroke();
                });
              }
            }
          }
        }

        const canvasImgGrids = new DrawGrids(
          gridsPosX,
          gridsPosY,
          canvasImg.width,
          canvasImg.height,
          tileSizeW,
          tileSizeH,
          gridsColor
        );

        const canvasMapGrids = new DrawGrids(
          gridsPosX,
          gridsPosY,
          canvas.width,
          canvas.height,
          tileSizeW,
          tileSizeH,
          gridsColor
        );

        /////////////////////////////////////////////////////////////////////
        /////////// GET/SHOW FILE AND CUT IMAGE INTO ARRAY//////////////////
        ///////////////////////////////////////////////////////////////////

        const tileImage = new Image();
        tileImage.src = "./images/tileset_32x32(new).png";
        tileImage.onload = cutImage;

        let imageTileParts = [];

        function cutImage() {
          let index = 1;
          for (let l = 0; l < tileImage.height / 32; l++) {
            for (let c = 0; c < tileImage.width / 32; c++) {
              imageTileParts.push({
                index,
                tileImage,
                x: c * tileSizeW,
                y: l * tileSizeH,
                w: tileSizeW,
                h: tileSizeH,
                x_draw: c * tileSizeW,
                y_draw: l * tileSizeH,
              });
              index++;
            }
          }
          showSpreadSheetImg();
        }

        function showSpreadSheetImg() {
          imageTileParts.forEach((el) => {
            ctxImg.drawImage(
              el.tileImage,
              el.x,
              el.y,
              el.w,
              el.h,
              el.x_draw,
              el.y_draw,
              el.w,
              el.h
            );
          });

          canvasImgGrids.draw();
          canvasMapGrids.draw();

          getMouseCanvasImgPos();
          getMouseCanvasPos();
        }

        //////////////////////////////////////////////////////////////////
        /////////// GET MOUSE POSITION AND EVENT CLICK //////////////////
        ////////////////////////////////////////////////////////////////

        let mouseCanvasImg = {};
        let mouseCanvasGrids = {};

        function getMouseCanvasImgPos() {
          const canvasImgPos = canvasImg.getBoundingClientRect();
          canvasImg.addEventListener("click", (e) => {
            mouseCanvasImg = {
              x: Math.floor((e.clientX - canvasImgPos.left) / tileSizeW) * tileSizeW,
              y: Math.floor((e.clientY - canvasImgPos.top) / tileSizeH) * tileSizeH,
            };
            compareMouseIdWithTiles();
          });
        }

        function getMouseCanvasPos() {
          const canvasGridsPos = canvas.getBoundingClientRect();
          canvas.addEventListener("mousedown", (e) => {
            mouseCanvasGrids = {
              x: Math.floor((e.clientX - canvasGridsPos.left) / tileSizeW) * tileSizeW,
              y: Math.floor((e.clientY - canvasGridsPos.top) / tileSizeH) * tileSizeH,
            };

            if (e.button == 0) {
              drawSelectedTileInGrids();
            } else if (e.button == 2) {
              deleteSelectedTile();
            }

            saveIdexedTiledMap();
          });
        }

        /////////////////////////////////////////////////////////////////
        /////////// COMPARE MOUSE WITH TILES POSITION //////////////////
        ///////////////////////////////////////////////////////////////

        let selectedTile = [];

        function compareMouseIdWithTiles() {
          for (let i = 0; i < imageTileParts.length; i++) {
            if (
              mouseCanvasImg.x == imageTileParts[i].x &&
              mouseCanvasImg.y == imageTileParts[i].y
            ) {
              // Delete last tile clicked in the array
              if (selectedTile.length >= 1) {
                selectedTile.shift();
              }

              selectedTile.push(imageTileParts[i]);
            }
          }
        }

        ///////////////////////////////////////////////////////////
        /////////// DRAW/DELETE SELECTED TILE IN GRIDS ///////////
        /////////////////////////////////////////////////////////

        // :: DRAW :: //
        function drawSelectedTileInGrids() {
          if (selectedTile <= 0) {
            console.log("Veuillez choisir une Tile !!!");
          } else {
            ctx.drawImage(
              selectedTile[0].tileImage,
              selectedTile[0].x,
              selectedTile[0].y,
              selectedTile[0].w,
              selectedTile[0].h,
              mouseCanvasGrids.x,
              mouseCanvasGrids.y,
              tileSizeW,
              tileSizeH
            );
          }
        }
        ///////////////////////////////
        //////////////////////////////
        //// TO RESOLVE ON !!!!! ////
        ////////////////////////////
        let array = [];

        function saveIdexedTiledMap() {
          for (let l = 0; l < canvas.height / 32; l++) {
            array[l] = [];
            for (let c = 0; c < canvas.width / 32; c++) {
              array[l][c] = 0;
            }
          }
          array[mouseCanvasGrids.y / 32][mouseCanvasGrids.x / 32] =
            selectedTile[0].index;

          console.log(array);
        }

        // :: DELETE :: //
        function deleteSelectedTile() {
          ctx.clearRect(mouseCanvasGrids.x, mouseCanvasGrids.y, tileSizeW, tileSizeH);
        }

        ////////////////////////////////////////////////
        /////////// CLEAR/SAVE CANVAS IMAGE ///////////
        //////////////////////////////////////////////

        clearCanvas.addEventListener("click", () => {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          canvasMapGrids.draw();
        });

        ////////////////////////////////////////////
        /////////// EXPORT CANVAS IMAGE ///////////
        //////////////////////////////////////////
        * {
          box-sizing: border-box;
        }

        body {
          margin: 0;
          margin-bottom: 50px;
          padding: 0;
        }

        .body {
          width: 900px;
          margin-bottom: 50px;
          background-color: #ccdaf0;
          margin: 20px auto;
          border-radius: 8px;
          background: linear-gradient(145deg, #dae9ff, #b8c4d8);
          box-shadow: 7px 7px 12px #818997, -7px -7px 12px #ffffff;
        }

        header {
          margin: 0 30px;
          display: flex;
          justify-content: space-between;
          align-items: baseline;
        }

        .content {
          display: flex;
        }

        aside {
          flex-grow: 1;
        }

        .canvas-content {
          margin: 0 30px;
          border-radius: 8px;
          background: #ccdaf0;
          box-shadow: inset 7px 7px 12px #818997, inset -7px -7px 12px #ffffff;
        }

        .img-container {
          padding: 10px;
          height: 200px;
        }
        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>Tile Map Editor</title>
            <link rel="stylesheet" href="./styles.css" />
          </head>
          <body>
            <div class="body">
              <header>
                <h1>Tile Map Editor</h1>
                <div>
                  <button id="btn-clearCanvas">clear canvas</button>
                  <button id="btn-exportImage">Export Map</button>
                </div>
              </header>

              <div class="content">
                <aside>
                  <form id="form">
                    <label>Config : </label>
                    <div class="config-container">
                      <div class="mapSize">
                        <label>Map Size : </label>
                        <label>width</label>
                        <input type="number" id="mapSizeW" />
                        <label>height</label>
                        <input type="number" id="mapSizeH" />
                      </div>
                      <div class="tileSize">
                        <label>Tile Size</label>
                        <input type="number" id="tileSize" />
                      </div>
                      <input id="submit" type="submit" value="Valider" />
                    </div>
                  </form>
                </aside>

                <div class="canvas-content">
                  <canvas
                    oncontextmenu="return false;"
                    width="608"
                    height="416"
                  ></canvas>
                </div>
              </div>
              <div id="img-container">
                <canvas
                  oncontextmenu="return false;"
                  id="canvasImg"
                  width="600"
                  height="200"
                ></canvas>
              </div>
            </div>
            <script src="./index.js"></script>
          </body>
        </html>


Solution

  • This mistake is in this function, you are clearing the array on every save:

    let array = [];
    
    function saveIdexedTiledMap() {
       for (let l = 0; l < canvas.height / 32; l++) {
          array[l] = [];
        for (let c = 0; c < canvas.width / 32; c++) {
          array[l][c] = 0;
        }
      }
      array[mouseCanvasGrids.y / 32][mouseCanvasGrids.x / 32] =
        selectedTile[0].index;
    
      console.log(array);
    }
    

    So you need to move the clearing outside like this:

    let array = [];
    
    for (let l = 0; l < canvas.height / 32; l++) {
      array[l] = [];
      for (let c = 0; c < canvas.width / 32; c++) {
        array[l][c] = 0;
      }
    }
    
    function saveIdexedTiledMap() {
      array[mouseCanvasGrids.y / 32][mouseCanvasGrids.x / 32] =
        selectedTile[0].index;
    
      console.log(array);
    }