Home > Software design >  When it is fixed to the floor while making Tetris with JavaScript, the color is fixed in one thing
When it is fixed to the floor while making Tetris with JavaScript, the color is fixed in one thing

Time:07-15

I want a variety of colors for each block, but when the Tetris block is fixed, the color is fixed in one.
I only want to solve the color change.
I can't solve it by myself, so I ask for this help.

The code is so long that I will attach a Github address.
https://github.com/kirk0201/tetris

I don't know exactly what is the problem, so I will raise all the code.
I hope you understand the my ugly code.

please help me...

<!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" />
    <style>
      #canvas {
        position: relative;
        left: 50%;
        transform: translateX(-50%);
        background-color: rgb(236, 231, 186);
        border: 1px solid red;
        background-color: cadetblue;
      }
      .container {
        display: grid;
        grid-template-columns: 300px 150px;
        gap: 10px;
      }
      .container .right_panel {
        background-color: aqua;
        font-weight: 700;
        padding: 0 10px;
      }
      .container .right_panel .title {
        text-align: center;
        font-size: 50px;
      }
      .container .right_panel .score {
        padding-bottom: 20px;
      }
    </style>
    <title>Tetris</title>
  </head>
  <body>
    <div >
      <canvas id="canvas"></canvas>
      <div >
        <div >Tetris</div>
        <div >Score : <span >0</span></div>
        <canvas id="newblock"></canvas>
      </div>
    </div>
    <script>
      const canvas = document.querySelector("#canvas");
      const context = canvas.getContext("2d");

      const newBlock = document.querySelector("#newblock");
      const newContext = newBlock.getContext("2d");

      const COLS = 10;
      const ROWS = 20;
      const BLOCKS = 30;

      const scale = 20;
      const tWidth = canvas.width / scale;
      const tHeight = canvas.height / scale;
      let ground = [];
      const BORDER = 5;
      let key;
      let initialScore = 0;
      // Playground
      context.canvas.width = COLS * BLOCKS;
      context.canvas.height = ROWS * BLOCKS;

      context.scale(scale, scale);
      newContext.scale(scale, scale);

      // 테트리스 랜덤 블럭
      function randomBlockShape() {
        const object = [
          {
            color: "blue",
            block: [
              [8, 8],
              [8, 8],
            ],
          },
          {
            color: "red",
            block: [
              [2, 2, 0],
              [0, 2, 2],
              [0, 0, 0],
            ],
          },
          {
            color: "yellow",
            block: [
              [0, 3, 3],
              [3, 3, 0],
              [0, 0, 0],
            ],
          },
          {
            color: "green",
            block: [
              [0, 4, 0],
              [4, 4, 4],
              [0, 0, 0],
            ],
          },
          {
            color: "purple",
            block: [
              [5, 0, 0],
              [5, 5, 5],
              [0, 0, 0],
            ],
          },
          {
            color: "brown",
            block: [
              [0, 0, 6],
              [6, 6, 6],
              [0, 0, 0],
            ],
          },
          {
            color: "cadetblue",
            block: [
              [0, 7, 0, 0],
              [0, 7, 0, 0],
              [0, 7, 0, 0],
              [0, 7, 0, 0],
            ],
          },
        ];
        const randomIndex = Math.floor(Math.random() * object.length);
        return object[randomIndex];
      }
      console.log(randomBlockShape());

      const player = {
        x: 6,
        y: 0,
        object: randomBlockShape(),
      };
      const area = {};
      // draw block
      function drawMatrix(object, x, y) {
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j]) {
              context.fillStyle = object.color;
              context.fillRect(x   j, y   i, 1, 1);
            }
          }
        }
      }

      // Fixed block Arena
      function drawArena(object) {
        for (let i = 1; i < ground.length - 1; i  ) {
          for (let j = 1; j < ground[i].length - 1; j  ) {
            if (ground[i][j] !== 0 && ground[i][j] !== 1) {
              context.fillStyle = object.color;
              context.fillRect(j - 1, i - 1, 1, 1);
            }
          }
        }
      }

      // aside 1
      function playground() {
        let tHeight = canvas.height / scale;
        let tWidth = canvas.width / scale;

        const side = new Array(tWidth   2).fill(1);
        ground.push(side);
        for (let i = 0; i < tHeight; i  ) {
          let row = new Array(tWidth).fill(0);
          row.push(1);
          row.unshift(1);

          ground.push(row);
        }
        ground.push(side);
      }

      // Collider
      function boxColider(player, ground) {
        for (let i = 0; i < player.object.block.length; i  ) {
          for (let j = 0; j < player.object.block[i].length; j  ) {
            if (
              player.object.block[i][j] &&
              ground[player.y   i   1][player.x   j   1]
            ) {
              return 1;
            }
          }
        }
        return 0;
      }

      // rotate (x, y) => (y, size - x) size = length -1
      function rotate(object) {
        let rotateBlock = [];
        object.block.forEach(() => {
          rotateBlock.push([]);
        });
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            rotateBlock[j][object.block.length - 1 - i] = object.block[i][j];
          }
        }
        return rotateBlock;
      }
      // collider-rotate
      function nonRotate(object) {
        let rotateBlock = [];
        object.block.forEach(() => {
          rotateBlock.push([]);
        });

        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            rotateBlock[j][i] = object.block[i][j];
          }
        }
        return rotateBlock;
      }

      let sec = 1000;
      let count = 0,
        speed = 30;

      let newShape;

      function draw() {
        context.fillStyle = "#000";
        context.fillRect(0, 0, canvas.width, canvas.height);

        drawArena(player.object);
        drawMatrix(player.object, player.x, player.y);
      }

      function update(time = 0) {
        let animate = requestAnimationFrame(update);
        let stop = cancelAnimationFrame(update);

        count  = speed;

        if (
          ground[1]
            .slice(1)
            .slice(0, -1)
            .some((cols) => cols !== 0)
        ) {
          return stop;
        }
        if (count >= sec) {
          player.y  ;
          count = 0;
        }
        if (key === "start") {
          newShape = randomBlockShape();
          key = "";
        }
        draw();

        preView(newShape);

        if (boxColider(player, ground)) {
          key = "start";
          addBlock(player.object, player.x, player.y - 1);
          player.object = newShape;
          deleteBlock();
          if (gameover()) {
            return 1;
          }
          player.y = 0;
          player.x = 6;
        }
      }

      // main
      function main() {
        window.addEventListener("keydown", keyHandler);
        playground();
        key = "start";
        update();
      }

      // preview
      function preView(object, x, y) {
        newContext.beginPath();
        newContext.fillStyle = "aqua";
        newContext.clearRect(
          0,
          0,
          newContext.canvas.width,
          newContext.canvas.height
        );
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j]) {
              newContext.fillStyle = object.color;
              newContext.fillRect(i, j, 1, 1);
            }
          }
        }
      }
      function addBlock(object, x, y) {
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j] > 0) {
              ground[y   i   1][x   j   1] = object.block[i][j];
            }
          }
        }
      }

      // END
      function gameover() {
        if (
          ground[1]
            .slice(1)
            .slice(0, -1)
            .some((cols) => cols !== 0)
        ) {
          // context.clearRect(0, 0, 0, 0);
          context.beginPath();
          context.fillStyle = "blue";
          context.fillRect(300, 0, 1, 1);
          context.font = "1px Arial";
          context.fillStyle = "red";
          context.fillText("Game Over", 20, 40);
          alert("GameOver");
        }
      }


      function deleteBlock() {
        let tWidth = canvas.width / scale;
        let n = ground.length - 2;
        let lastBlock = ground.filter((rows) => rows.some((n) => n === 0));
        let deleteBlock = ground.filter((rows) => rows.every((n) => n !== 0));
        let deleteNumber = deleteBlock.length - 2;

        if (deleteNumber > 0) {

          ground.splice(ground.length - 1 - deleteNumber, deleteNumber);
          for (let i = 0; i < deleteNumber; i  ) {
            initialScore  = 10;
            const score = document.querySelector(".score_number");
            score.innerText = `${initialScore}`;
            let row = new Array(tWidth).fill(0);
            row.push(1);
            row.unshift(1);
            ground.splice(1, 0, row);
          }
        }
        return ground;
      }

      function keyHandler(e) {
        // console.log(e);
        const inputKey = e.keyCode;

        const KEY = {
          LEFT: 37,
          UP: 38,
          RIGHT: 39,
          DOWN: 40,
          SPACE: 32,
        };

        switch (inputKey) {
          case KEY.SPACE:
            break;
          case KEY.UP:
            player.object.block = rotate(player.object);
            if (boxColider(player, ground)) {
              player.object.block = nonRotate(player.object);
            }
            break;
          case KEY.DOWN:
            player.y  ;

            break;
          case KEY.LEFT:
            player.x--;
            if (boxColider(player, ground)) {
              player.x  ;
            }
            break;
          case KEY.RIGHT:
            player.x  ;
            if (boxColider(player, ground)) {
              player.x--;
            }
            break;
        }
      }

      main();
    </script>
  </body>
</html>

CodePudding user response:

.as-console-wrapper { max-height: 0% !important }
<!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" />
    <style>
      #canvas {
        position: relative;
        left: 50%;
        transform: translateX(-50%);
        background-color: rgb(236, 231, 186);
        border: 1px solid red;
        background-color: cadetblue;
      }
      .container {
        display: grid;
        grid-template-columns: 300px 150px;
        gap: 10px;
      }
      .container .right_panel {
        background-color: aqua;
        font-weight: 700;
        padding: 0 10px;
      }
      .container .right_panel .title {
        text-align: center;
        font-size: 50px;
      }
      .container .right_panel .score {
        padding-bottom: 20px;
      }
    </style>
    <title>Tetris</title>
  </head>
  <body>
    <div >
      <canvas id="canvas"></canvas>
      <div >
        <div >Tetris</div>
        <div >Score : <span >0</span></div>
        <canvas id="newblock"></canvas>
      </div>
    </div>
    <script>
      const canvas = document.querySelector("#canvas");
      const context = canvas.getContext("2d");

      const newBlock = document.querySelector("#newblock");
      const newContext = newBlock.getContext("2d");

      const COLS = 10;
      const ROWS = 20;
      const BLOCKS = 30;

      const scale = 20;
      const tWidth = canvas.width / scale;
      const tHeight = canvas.height / scale;
      let ground = [];
      let colorGround = [];
      const BORDER = 5;
      let key;
      let initialScore = 0;
      // Playground
      context.canvas.width = COLS * BLOCKS;
      context.canvas.height = ROWS * BLOCKS;

      context.scale(scale, scale);
      newContext.scale(scale, scale);

      // 테트리스 랜덤 블럭
      function randomBlockShape() {
        const object = [
          {
            color: "blue",
            block: [
              [8, 8],
              [8, 8],
            ],
          },
          {
            color: "red",
            block: [
              [2, 2, 0],
              [0, 2, 2],
              [0, 0, 0],
            ],
          },
          {
            color: "yellow",
            block: [
              [0, 3, 3],
              [3, 3, 0],
              [0, 0, 0],
            ],
          },
          {
            color: "green",
            block: [
              [0, 4, 0],
              [4, 4, 4],
              [0, 0, 0],
            ],
          },
          {
            color: "purple",
            block: [
              [5, 0, 0],
              [5, 5, 5],
              [0, 0, 0],
            ],
          },
          {
            color: "brown",
            block: [
              [0, 0, 6],
              [6, 6, 6],
              [0, 0, 0],
            ],
          },
          {
            color: "cadetblue",
            block: [
              [0, 7, 0, 0],
              [0, 7, 0, 0],
              [0, 7, 0, 0],
              [0, 7, 0, 0],
            ],
          },
        ];
        const randomIndex = Math.floor(Math.random() * object.length);
        return object[randomIndex];
      }
      console.log(randomBlockShape());

      const player = {
        x: 6,
        y: 0,
        object: randomBlockShape(),
      };
      const area = {};
      // draw block
      function drawMatrix(object, x, y) {
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j]) {
              context.fillStyle = object.color;
              context.fillRect(x   j, y   i, 1, 1);
            }
          }
        }
      }

      // Fixed block Arena
      function drawArena(object) {
        for (let i = 1; i < ground.length - 1; i  ) {
          for (let j = 1; j < ground[i].length - 1; j  ) {
            if (ground[i][j] !== 0 && ground[i][j] !== 1) {
              context.fillStyle = colorGround[i][j];
              context.fillRect(j - 1, i - 1, 1, 1);
            }
          }
        }
      }

      // aside 1
      function playground() {
        let tHeight = canvas.height / scale;
        let tWidth = canvas.width / scale;

        const side = new Array(tWidth   2).fill(1);
        ground.push(side);
        colorGround.push(new Array(tWidth   2).fill("black"));
        for (let i = 0; i < tHeight; i  ) {
          let row = new Array(tWidth).fill(0);
          row.push(1);
          row.unshift(1);

          ground.push(row);
          const colorRow = new Array(tWidth).fill("black");
          colorRow.push("black");
          colorRow.unshift("black");
          colorGround.push(colorRow);
        }
        ground.push(side);
        colorGround.push(new Array(tWidth   2).fill("black"))
      }

      // Collider
      function boxColider(player, ground) {
        for (let i = 0; i < player.object.block.length; i  ) {
          for (let j = 0; j < player.object.block[i].length; j  ) {
            if (
              player.object.block[i][j] &&
              ground[player.y   i   1][player.x   j   1]
            ) {
              return 1;
            }
          }
        }
        return 0;
      }

      // rotate (x, y) => (y, size - x) size = length -1
      function rotate(object) {
        let rotateBlock = [];
        object.block.forEach(() => {
          rotateBlock.push([]);
        });
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            rotateBlock[j][object.block.length - 1 - i] = object.block[i][j];
          }
        }
        return rotateBlock;
      }
      // collider-rotate
      function nonRotate(object) {
        let rotateBlock = [];
        object.block.forEach(() => {
          rotateBlock.push([]);
        });

        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            rotateBlock[j][i] = object.block[i][j];
          }
        }
        return rotateBlock;
      }

      let sec = 1000;
      let count = 0,
        speed = 30;

      let newShape;

      function draw() {
        context.fillStyle = "#000";
        context.fillRect(0, 0, canvas.width, canvas.height);

        drawArena(player.object);
        drawMatrix(player.object, player.x, player.y);
      }

      function update(time = 0) {
        let animate = requestAnimationFrame(update);
        let stop = cancelAnimationFrame(update);

        count  = speed;

        if (
          ground[1]
            .slice(1)
            .slice(0, -1)
            .some((cols) => cols !== 0)
        ) {
          return stop;
        }
        if (count >= sec) {
          player.y  ;
          count = 0;
        }
        if (key === "start") {
          newShape = randomBlockShape();
          key = "";
        }
        draw();

        preView(newShape);

        if (boxColider(player, ground)) {
          key = "start";
          addBlock(player.object, player.x, player.y - 1);
          player.object = newShape;
          deleteBlock();
          if (gameover()) {
            return 1;
          }
          player.y = 0;
          player.x = 6;
        }
      }

      // main
      function main() {
        window.addEventListener("keydown", keyHandler);
        playground();
        key = "start";
        update();
      }

      // preview
      function preView(object, x, y) {
        newContext.beginPath();
        newContext.fillStyle = "aqua";
        newContext.clearRect(
          0,
          0,
          newContext.canvas.width,
          newContext.canvas.height
        );
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j]) {
              newContext.fillStyle = object.color;
              newContext.fillRect(i, j, 1, 1);
            }
          }
        }
      }
      function addBlock(object, x, y) {
        for (let i = 0; i < object.block.length; i  ) {
          for (let j = 0; j < object.block[i].length; j  ) {
            if (object.block[i][j] > 0) {
              ground[y   i   1][x   j   1] = object.block[i][j];
              colorGround[y   i   1][x   j   1] = object.color;
            }
          }
        }
      }

      // END
      function gameover() {
        if (
          ground[1]
            .slice(1)
            .slice(0, -1)
            .some((cols) => cols !== 0)
        ) {
          // context.clearRect(0, 0, 0, 0);
          context.beginPath();
          context.fillStyle = "blue";
          context.fillRect(300, 0, 1, 1);
          context.font = "1px Arial";
          context.fillStyle = "red";
          context.fillText("Game Over", 20, 40);
          alert("GameOver");
        }
      }


      function deleteBlock() {
        let tWidth = canvas.width / scale;
        let n = ground.length - 2;
        let lastBlock = ground.filter((rows) => rows.some((n) => n === 0));
        let deleteBlock = ground.filter((rows) => rows.every((n) => n !== 0));
        let deleteNumber = deleteBlock.length - 2;

        if (deleteNumber > 0) {

          ground.splice(ground.length - 1 - deleteNumber, deleteNumber);
          for (let i = 0; i < deleteNumber; i  ) {
            initialScore  = 10;
            const score = document.querySelector(".score_number");
            score.innerText = `${initialScore}`;
            let row = new Array(tWidth).fill(0);
            row.push(1);
            row.unshift(1);
            ground.splice(1, 0, row);
          }
        }
        return ground;
      }

      function keyHandler(e) {
        // console.log(e);
        const inputKey = e.keyCode;

        const KEY = {
          LEFT: 37,
          UP: 38,
          RIGHT: 39,
          DOWN: 40,
          SPACE: 32,
        };

        switch (inputKey) {
          case KEY.SPACE:
            break;
          case KEY.UP:
            player.object.block = rotate(player.object);
            if (boxColider(player, ground)) {
              player.object.block = nonRotate(player.object);
            }
            break;
          case KEY.DOWN:
            player.y  ;

            break;
          case KEY.LEFT:
            player.x--;
            if (boxColider(player, ground)) {
              player.x  ;
            }
            break;
          case KEY.RIGHT:
            player.x  ;
            if (boxColider(player, ground)) {
              player.x--;
            }
            break;
        }
      }

      main();
    </script>
  </body>
</html>

This is my first snippet, but should work :D. In your code there was no correlation of the color to the ground index. i did not dive to deeply into your logic, but created a new array color ground, that follows the same steps as the ground array, and then when dropping the block into the ground, adding its color to the color ground, while later accessing the same index when drawing the arena. Hope that helps:

  • Related