<!DOCTYPE html>
<html>
<head>
  <title>Tetris</title>
  <style type="text/css">
    body {
      margin: 0;
      padding: 0;
      background-color: #000;
    }
    canvas {
      background-color: #eee;
    }
  </style>
  <script type="text/javascript">
    // the game itself
    let game;
    // when the window loads
    window.onload = () => {
      // create the game instance
      game = new Tetris();
    };
    // Tetris class
    class Tetris {
      constructor() {
        // game properties
        this.canvas = document.createElement("canvas");
        this.ctx = this.canvas.getContext("2d");
        this.cols = 10;
        this.rows = 20;
        this.blockSize = 30;
        this.width = this.blockSize * this.cols;
        this.height = this.blockSize * this.rows;
        // create the board
        this.board = new Array(this.rows);
        for (let r = 0; r < this.rows; r++) {
          this.board[r] = new Array(this.cols);
        }
        // pieces that are used in the game
        this.pieces = [
          [1, 1, 1, 1],
          [1, 1, 1, 0,
           1],
          [1, 1, 1, 0,
           0, 0, 1],
          [1, 1, 0, 0,
           1, 1],
          [1, 1, 0, 0,
           0, 1, 1],
          [0, 1, 1, 0,
           1, 1],
          [0, 1, 0, 0,
           1, 1, 1]
        ];
        // set the colors of the pieces
        this.colors = ['cyan', 'blue', 'orange', 'yellow', 'green', 'purple', 'red'];
        // start a new game
        this.newGame();
      }
      // start a new game
      newGame() {
        // add the canvas to the body of the page
        document.body.appendChild(this.canvas);
        this.canvas.width = this.width;
        this.canvas.height = this.height;
        // add the listeners
        this.ctx.canvas.addEventListener('keydown', this.keyDown.bind(this), false);
        // start the game loop
        this.interval = setInterval(this.update.bind(this), 1000);
        // create a new piece
        this.newPiece();
      }
      // game loop
      update() {
        // move the piece down
        this.activePiece.y += 1;
        // check if the piece hit the bottom or a block
        if (this.checkCollision()) {
          // if it did, add the piece to the board
          this.addPiece();
          // start a new piece
          this.newPiece();
        }
        // check if there are any lines to clear
        this.clearLines();
        // update the board
        this.updateBoard();
      }
      // create a new piece
      newPiece() {
        // random number for the pieces
        let random = Math.floor(Math.random() * this.pieces.length);
        // random number for the colors
        let randomColor = Math.floor(Math.random() * this.colors.length);
        // set the new piece
        this.activePiece = {
          x: 3,
          y: 0,
          shape: this.pieces[random],
          color: this.colors[randomColor]
        };
      }
      // update the board
      updateBoard() {
        // clear the board
        this.ctx.clearRect(0, 0, this.width, this.height);
        // draw the active piece
        this.drawPiece(this.activePiece.x, this.activePiece.y, this.activePiece.shape, this.activePiece.color);
        // draw the blocks in the board
        for (let r = 0; r < this.rows; r++) {
          for (let c = 0; c < this.cols; c++) {
            // check if the block is set
            if (this.board[r][c] !== 0) {
              let blockX = c * this.blockSize;
              let blockY = r * this.blockSize;
              // draw the block
              this.ctx.fillStyle = this.board[r][c];
              this.ctx.fillRect(blockX, blockY, this.blockSize, this.blockSize);
              this.ctx.strokeStyle = 'black';
              this.ctx.strokeRect(blockX, blockY, this.blockSize, this.blockSize);
            }
          }
        }
      }
      // draw a piece
      drawPiece(x, y, shape, color) {
        // loop through the shape
        for (let r = 0; r < shape.length; r++) {
          for (let c = 0; c < shape.length; c++) {
            // check if the block is set
            if (shape[r][c] !== 0) {
              let blockX = (x + c) * this.blockSize;
              let blockY = (y + r) * this.blockSize;
              // draw the block
              this.ctx.fillStyle = color;
              this.ctx.fillRect(blockX, blockY, this.blockSize, this.blockSize);
              this.ctx.strokeStyle = 'black';
              this.ctx.strokeRect(blockX, blockY, this.blockSize, this.blockSize);
            }
          }
        }
      }
      // move the piece left
      movePieceLeft() {
        this.activePiece.x -= 1;
        if (this.checkCollision()) {
          this.activePiece.x += 1;
        }
      }
      // move the piece right
      movePieceRight() {
        this.activePiece.x += 1;
        if (this.checkCollision()) {
          this.activePiece.x -= 1;
        }
      }
      // rotate the piece
      rotatePiece() {
        // get the next rotation
        let nextRotation = this.activePiece.shape[(this.activePiece.shape.length + 1) % this.activePiece.shape.length];
        // check if the rotation is valid
        let valid = true;
        for (let r = 0; r < nextRotation.length; r++) {
          for (let c = 0; c < nextRotation.length; c++) {
            // check if the block is set
            if (nextRotation[r][c] !== 0) {
              let x = this.activePiece.x + c;
              let y = this.activePiece.y + r;
              // check if it is inside the board
              if (x < 0 || x >= this.cols || y >= this.rows) {
                valid = false;
              }
              // check if it is inside a block
              if (y < 0) {
                continue;
              }
              if (this.board[y][x] !== 0) {
                valid = false;
              }
            }
          }
        }
        // set the new rotation
        if (valid) {
          this.activePiece.shape = nextRotation;
        }
      }
      // check for collision
      checkCollision() {
        // loop through the piece
        for (let r = 0; r < this.activePiece.shape.length; r++) {
          for (let c = 0; c < this.activePiece.shape.length; c++) {
            // check if the block is set
            if (this.activePiece.shape[r][c] !== 0) {
              let x = this.activePiece.x + c;
              let y = this.activePiece.y + r;
              // check if it is inside the board
              if (x < 0 || x >= this.cols || y >= this.rows) {
                return true;
              }
              // check if it is inside a block
              if (y < 0) {
                continue;
              }
              if (this.board[y][x] !== 0) {
                return true;
              }
            }
          }
        }
        return false;
      }
      // add the piece to the board
      addPiece() {
        // loop through the piece
        for (let r = 0; r < this.activePiece.shape.length; r++) {
          for (let c = 0; c < this.activePiece.shape.length; c++) {
            // check if the block is set
            if (this.activePiece.shape[r][c] !== 0) {
              let x = this.activePiece.x + c;
              let y = this.activePiece.y + r;
              // check if it is inside the board
              if (x < 0 || x >= this.cols || y >= this.rows) {
                continue;
              }
              // add the block to the board
              this.board[y][x] = this.activePiece.color;
            }
          }
        }
      }
      // clear lines
      clearLines() {
        // loop through the rows
        for (let r = 0; r < this.rows; r++) {
          // check if the row is full
          let full = true;
          for (let c = 0; c < this.cols; c++) {
            if (this.board[r][c] === 0) {
              full = false;
              break;
            }
          }
          // clear the line
          if (full) {
            // shift the rows down
            for (let i = r; i > 0; i--) {
              this.board[i] = this.board[i - 1];
            }
            // reset the first row
            this.board[0] = new Array(this.cols);
            // increase the score
          }
        }
      }
      // key down listener
      keyDown(e) {
        // check which key was pressed
        switch (e.keyCode) {
          case 37: // left
            this.movePieceLeft();
            break;
          case 38: // up
            this.rotatePiece();
            break;
          case 39: // right
            this.movePieceRight();
            break;
          case 40: // down
            this.activePiece.y += 1;
            if (this.checkCollision()) {
              this.activePiece.y -= 1;
              this.addPiece();
              this.newPiece();
            }
            break;
        }
      }
    }
  </script>
</head>
<body>
</body>
</html>
HTML Tetris Game Complete Code - Build Your Own Tetris Game

原文地址: https://www.cveoy.top/t/topic/losE 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录