在这里插入图片描述
index.axml

<!-- 容器添加动态内边距,并移除 justify-content:center 的影响 -->
<view class="container" style="padding-top:{{safeTop}}px;">
  <!-- 开始模态框 -->
  <view class="modal" a:if="{{showStartModal}}">
    <view class="modal-content">
      <text class="modal-title">俄罗斯方块</text>
      <text>调整速度:</text>
      <slider min="5" max="30" value="{{speed}}" onChange="speedChange" />
      <button type="primary" onTap="startGame">开始游戏</button>
    </view>
  </view>

  <!-- 暂停/结束模态框 -->
  <view class="modal" a:if="{{showPauseModal}}">
    <view class="modal-content">
      <text class="modal-title">{{pauseModalTitle}}</text>
      <text>调整速度:</text>
      <slider min="5" max="30" value="{{speed}}" onChange="speedChange" />
      <button a:if="{{pauseModalTitle === '暂停'}}" type="primary" onTap="resume">继续</button>
      <button type="primary" onTap="restart">重新开始</button>
      <button type="primary" onTap="exit">退出</button>
    </view>
  </view>

  <!-- 游戏画布(同时设置 width/height 属性和 style,确保绘制和显示一致) -->
  <canvas
    id="gameCanvas"
    class="game-canvas"
    width="{{canvasWidth}}"
    height="{{canvasHeight}}"
    style="width:{{canvasWidth}}px;height:{{canvasHeight}}px;max-width:100%;"
  ></canvas>

  <!-- 得分显示 -->
  <view class="score">得分:{{score}}</view>

  <!-- 控制按钮 -->
  <view class="controls">
    <button class="ctrl-btn" onTap="moveLeft"></button>
    <button class="ctrl-btn" onTap="moveRight"></button>
    <button class="ctrl-btn" onTap="rotate"></button>
    <button class="ctrl-btn" onTap="dropDown"></button>
    <button class="ctrl-btn" onTap="pause">⏸️</button>
  </view>
</view>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start; /* 改为从顶部排列,避免居中挤压 */
  height: 100vh;
  background: linear-gradient(135deg, #1e3c72, #2a5298);
  font-family: Arial, sans-serif;
  box-sizing: border-box; /* 确保内边距计入高度计算 */
  /* 顶部内边距已在行内样式通过 safeTop 动态绑定,不在 ACSS 中写死 */
  padding-left: 20rpx;
  padding-right: 20rpx;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 100;
}

.modal-content {
  background: #fff;
  padding: 40rpx;
  border-radius: 20rpx;
  text-align: center;
  width: 80%;
}

.modal-title {
  font-size: 48rpx;
  margin-bottom: 20rpx;
  display: block;
  color: #333;
}

.game-canvas {
  display: block;
  margin: 20rpx auto;
  border: 3px solid #fff;
  border-radius: 10px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
  /* 保证画布宽度不超过屏幕,高度自适应,保持比例 */
  max-width: 100%;
  height: auto;
}

.score {
  margin-top: 5rpx;
  background: rgba(255, 255, 255, 0.1);
  padding: 15rpx 15rpx;
  border-radius: 10rpx;
  color: white;
  font-size: 30rpx;
  font-weight: bold;
}

.controls {
  margin-top: 10rpx;
  display: flex;
  gap: 25rpx;
  flex-wrap: wrap; /* 防止按钮在小屏幕上换行 */
  justify-content: center;
}

.ctrl-btn {
  width: 100rpx;
  height: 100rpx;
  border-radius: 50rpx;
  background: #ff6b6b;
  color: white;
  font-size: 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2);
}

.ctrl-btn:active {
  background: #ff8787;
  transform: scale(0.95);
}

index.js

const BOARD_WIDTH = 10;
const BOARD_HEIGHT = 20;
const CELL_SIZE = 30; // 每个格子像素大小,画布尺寸 300x600

Page({
  data: {
    safeTop: 20,
    score: 0,
    gameOver: false,
    paused: false,
    showStartModal: true,
    showPauseModal: false,
    pauseModalTitle: '暂停',
    speed: 10, // 下落速度,范围 5-30
    canvasWidth: BOARD_WIDTH * CELL_SIZE,
    canvasHeight: BOARD_HEIGHT * CELL_SIZE
  },

  onLoad() {
    try {
      const systemInfo = dd.getSystemInfoSync();
      // 状态栏高度(单位 px),不同手机可能不同
      const safeTop = systemInfo.statusBarHeight || 20;
      this.setData({ safeTop });
    } catch (e) {
      console.warn('获取状态栏高度失败', e);
    }
    this.board = new Board(BOARD_WIDTH, BOARD_HEIGHT);
    this.currentPiece = new Piece(this.board);
    this.ctx = null;
    this.timer = null;
  },

  onReady() {
    this.ctx = dd.createCanvasContext('gameCanvas');
    this.draw();
  },

  onUnload() {
    this.clearTimer();
  },

  // 清除定时器
  clearTimer() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
    }
  },

  // 开始游戏(点击开始按钮)
  startGame() {
    this.setData({ showStartModal: false });
    this.resetGame();
    this.startLoop();
  },

  // 重置游戏
  resetGame() {
    this.board = new Board(BOARD_WIDTH, BOARD_HEIGHT);
    this.currentPiece = new Piece(this.board);
    this.setData({ score: 0, gameOver: false, paused: false });
    this.draw();
  },

  // 启动游戏循环
  startLoop() {
    this.clearTimer();
    const interval = 5000 / this.data.speed; // 根据速度计算间隔(毫秒)
    this.timer = setInterval(() => {
      if (!this.data.paused && !this.data.gameOver) {
        this.updatePiece();
      }
    }, interval);
  },

  // 更新方块(下落一步)
  updatePiece() {
    const nextPiece = this.currentPiece.clone();
    nextPiece.y++;

    if (this.board.checkCollision(nextPiece)) {
      // 如果方块超出顶部,游戏结束
      if (this.currentPiece.y < 0) {
        this.setData({ gameOver: true, showPauseModal: true, pauseModalTitle: '游戏结束' });
        this.clearTimer();
      } else {
        this.board.addPiece(this.currentPiece);
        const lines = this.board.clearLines();
        if (lines > 0) {
          this.setData({ score: this.data.score + lines * 100 });
        }
        this.currentPiece = new Piece(this.board);
        // 检查新方块是否立即碰撞
        if (this.board.checkCollision(this.currentPiece)) {
          this.setData({ gameOver: true, showPauseModal: true, pauseModalTitle: '游戏结束' });
          this.clearTimer();
        }
      }
    } else {
      this.currentPiece.y++;
    }
    this.draw();
  },

  // 绘制游戏板
  draw() {
    if (!this.ctx) return;
    const ctx = this.ctx;
    const w = this.data.canvasWidth;
    const h = this.data.canvasHeight;

    ctx.clearRect(0, 0, w, h);
    // 背景填充
    ctx.fillStyle = '#4facfe';
    ctx.fillRect(0, 0, w, h);

    // 绘制网格线(白色细线)
    ctx.strokeStyle = '#ffffff';
    ctx.lineWidth = 1;
    for (let i = 0; i <= BOARD_WIDTH; i++) {
      ctx.beginPath();
      ctx.moveTo(i * CELL_SIZE, 0);
      ctx.lineTo(i * CELL_SIZE, h);
      ctx.stroke();
    }
    for (let i = 0; i <= BOARD_HEIGHT; i++) {
      ctx.beginPath();
      ctx.moveTo(0, i * CELL_SIZE);
      ctx.lineTo(w, i * CELL_SIZE);
      ctx.stroke();
    }

    // 绘制已固定的方块
    for (let y = 0; y < BOARD_HEIGHT; y++) {
      for (let x = 0; x < BOARD_WIDTH; x++) {
        if (this.board.grid[y][x] === 1) {
          ctx.fillStyle = '#0080ff';
          ctx.fillRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
        }
      }
    }

    // 绘制当前方块
    if (this.currentPiece) {
      ctx.fillStyle = this.currentPiece.getColor();
      for (let i = 0; i < this.currentPiece.shape.length; i++) {
        for (let j = 0; j < this.currentPiece.shape[i].length; j++) {
          if (this.currentPiece.shape[i][j] === 1) {
            const x = (this.currentPiece.x + j) * CELL_SIZE + 1;
            const y = (this.currentPiece.y + i) * CELL_SIZE + 1;
            ctx.fillRect(x, y, CELL_SIZE - 2, CELL_SIZE - 2);
          }
        }
      }
    }

    ctx.draw();
  },

  // 左移
  moveLeft() {
    if (this.data.paused || this.data.gameOver) return;
    const next = this.currentPiece.clone();
    next.x--;
    if (!this.board.checkCollision(next)) {
      this.currentPiece.x--;
      this.draw();
    }
  },

  // 右移
  moveRight() {
    if (this.data.paused || this.data.gameOver) return;
    const next = this.currentPiece.clone();
    next.x++;
    if (!this.board.checkCollision(next)) {
      this.currentPiece.x++;
      this.draw();
    }
  },

  // 旋转
  rotate() {
    if (this.data.paused || this.data.gameOver) return;
    const next = this.currentPiece.clone();
    next.rotate();
    if (!this.board.checkCollision(next)) {
      this.currentPiece.shape = next.shape;
      this.draw();
    }
  },

  // 快速下落
  dropDown() {
    if (this.data.paused || this.data.gameOver) return;
    // 一直向下移动直到碰撞
    while (!this.board.checkCollision(this.currentPiece.clone({ y: this.currentPiece.y + 1 }))) {
      this.currentPiece.y++;
    }
    // 触底后固定
    if (this.currentPiece.y < 0) {
      this.setData({ gameOver: true, showPauseModal: true, pauseModalTitle: '游戏结束' });
      this.clearTimer();
    } else {
      this.board.addPiece(this.currentPiece);
      const lines = this.board.clearLines();
      if (lines > 0) {
        this.setData({ score: this.data.score + lines * 100 });
      }
      this.currentPiece = new Piece(this.board);
      if (this.board.checkCollision(this.currentPiece)) {
        this.setData({ gameOver: true, showPauseModal: true, pauseModalTitle: '游戏结束' });
        this.clearTimer();
      }
    }
    this.draw();
  },

  // 暂停
  pause() {
    if (this.data.gameOver) return;
    this.setData({ paused: true, showPauseModal: true, pauseModalTitle: '暂停' });
  },

  // 继续
  resume() {
    this.setData({ paused: false, showPauseModal: false });
  },

  // 重新开始
  restart() {
    this.resetGame();
    this.startLoop();
    this.setData({ showPauseModal: false });
  },

  // 退出(返回上一页)
  exit() {
    dd.navigateBack();
  },

  // 速度滑块变化
  speedChange(e) {
    const val = e.detail.value;
    this.setData({ speed: val });
    // 如果游戏正在运行,重启循环以应用新速度
    if (this.timer) {
      this.startLoop();
    }
  }
});

// 游戏板类
class Board {
  constructor(width, height) {
    this.width = width;
    this.height = height;
    this.grid = Array(height).fill().map(() => Array(width).fill(0));
  }

  // 碰撞检测
  checkCollision(piece) {
    for (let i = 0; i < piece.shape.length; i++) {
      for (let j = 0; j < piece.shape[i].length; j++) {
        if (piece.shape[i][j] === 1) {
          const x = piece.x + j;
          const y = piece.y + i;
          if (y >= this.height) return true; // 超出底部
          if (x < 0 || x >= this.width) return true; // 超出左右边界
          if (y >= 0 && this.grid[y][x] === 1) return true; // 与其他方块重叠
        }
      }
    }
    return false;
  }

  // 将方块固定到游戏板
  addPiece(piece) {
    for (let i = 0; i < piece.shape.length; i++) {
      for (let j = 0; j < piece.shape[i].length; j++) {
        if (piece.shape[i][j] === 1) {
          const x = piece.x + j;
          const y = piece.y + i;
          if (y >= 0 && y < this.height && x >= 0 && x < this.width) {
            this.grid[y][x] = 1;
          }
        }
      }
    }
  }

  // 消除满行并返回消除行数
  clearLines() {
    let linesCleared = 0;
    for (let y = this.height - 1; y >= 0; y--) {
      let full = true;
      for (let x = 0; x < this.width; x++) {
        if (this.grid[y][x] === 0) {
          full = false;
          break;
        }
      }
      if (full) {
        this.grid.splice(y, 1);
        this.grid.unshift(Array(this.width).fill(0));
        linesCleared++;
        y++; // 重新检查当前行
      }
    }
    return linesCleared;
  }
}

// 方块类
class Piece {
  constructor(board) {
    this.shapes = [
      [[1, 1, 1, 1]], // I
      [[1, 1], [1, 1]], // O
      [[1, 1, 1], [0, 1, 0]], // T
      [[1, 1, 1], [1, 0, 0]], // L
      [[1, 1, 1], [0, 0, 1]], // J
      [[1, 1, 0], [0, 1, 1]], // S
      [[0, 1, 1], [1, 1, 0]] // Z
    ];
    this.colors = [
      '#00ffff', // I 青色
      '#ffff00', // O 黄色
      '#800080', // T 紫色
      '#ffa500', // L 橙色
      '#0000ff', // J 蓝色
      '#00ff00', // S 绿色
      '#ff0000'  // Z 红色
    ];
    const idx = Math.floor(Math.random() * this.shapes.length);
    this.shape = this.shapes[idx].map(row => [...row]); // 深拷贝形状
    this.colorIdx = idx;
    this.board = board;
    this.x = Math.floor(board.width / 2) - Math.floor(this.shape[0].length / 2);
    this.y = -this.shape.length; // 起始位置在板子上方
  }

  // 克隆当前方块,可覆盖属性
  clone(mod = {}) {
    const newPiece = new Piece(this.board);
    newPiece.shape = this.shape.map(row => [...row]);
    newPiece.x = this.x;
    newPiece.y = this.y;
    newPiece.colorIdx = this.colorIdx;
    Object.assign(newPiece, mod);
    return newPiece;
  }

  // 获取颜色
  getColor() {
    return this.colors[this.colorIdx];
  }

  // 顺时针旋转
  rotate() {
    const newShape = [];
    for (let i = 0; i < this.shape[0].length; i++) {
      newShape[i] = [];
      for (let j = 0; j < this.shape.length; j++) {
        newShape[i][j] = this.shape[this.shape.length - 1 - j][i];
      }
    }
    this.shape = newShape;
  }
}

参考

<!DOCTYPE html>
<html>
<head>
    <title>俄罗斯方块</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
    <style>
        body {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #1e3c72, #2a5298);
            font-family: Arial, sans-serif;
        }
        canvas {
            border: 3px solid #fff;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
            display: none;
        }
        #scoreDisplay {
            margin-top: 20px;
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
            color: white;
            font-size: 1.2em;
            font-weight: bold;
        }
        #startModal, #pauseModal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .modal-content {
            background: #fff;
            padding: 20px;
            border-radius: 10px;
            text-align: center;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
        }
        .modal-content h2 {
            margin: 0 0 20px;
            color: #333;
        }
        .modal-content button {
            margin: 10px;
            padding: 10px 20px;
            font-size: 1em;
            cursor: pointer;
            border: none;
            border-radius: 5px;
            background: #ff6b6b;
            color: white;
            transition: background 0.3s;
        }
        .modal-content button:hover {
            background: #ff8787;
        }
        .modal-content input[type="range"] {
            width: 200px;
            margin: 20px 0;
            accent-color: #ff6b6b;
        }
    </style>
</head>
<body>
<div id="startModal">
    <div class="modal-content">
        <h2>俄罗斯方块</h2>
        <p>调整速度:</p>
        <input type="range" id="startSpeedSlider" min="5" max="30" value="10">
        <button id="startButton">开始游戏</button>
    </div>
</div>
<div id="pauseModal" style="display: none;">
    <div class="modal-content">
        <h2 id="pauseModalTitle">暂停</h2>
        <p>调整速度:</p>
        <input type="range" id="pauseSpeedSlider" min="5" max="30" value="10">
        <button id="resumeButton">继续</button>
        <button id="restartButton">重新开始</button>
        <button id="exitButton">退出</button>
    </div>
</div>
<div id="scoreDisplay" style="display: none;">得分:0</div>
<script>
    let board;
    let currentPiece;
    let score = 0;
    let gameOver = false;
    let paused = false;
    let frameRateValue = 10;
    let gameStarted = false;

    function setup() {
        let canvas = createCanvas(300, 600);
        canvas.elt.style.display = 'none';
        board = new Board(10, 20);
        currentPiece = new Piece();
        frameRate(frameRateValue);

        document.getElementById('startButton').addEventListener('click', () => {
            document.getElementById('startModal').style.display = 'none';
            canvas.elt.style.display = 'block';
            document.getElementById('scoreDisplay').style.display = 'block';
            gameStarted = true;
            frameRateValue = parseInt(document.getElementById('startSpeedSlider').value);
        });

        document.getElementById('resumeButton').addEventListener('click', () => {
            if (!gameOver) {
                document.getElementById('pauseModal').style.display = 'none';
                paused = false;
                frameRateValue = parseInt(document.getElementById('pauseSpeedSlider').value);
            }
        });

        document.getElementById('restartButton').addEventListener('click', () => {
            window.location.reload();
        });

        document.getElementById('exitButton').addEventListener('click', () => {
            window.close();
        });

        document.getElementById('startSpeedSlider').addEventListener('input', () => {
            frameRateValue = parseInt(document.getElementById('startSpeedSlider').value);
            document.getElementById('pauseSpeedSlider').value = frameRateValue;
        });

        document.getElementById('pauseSpeedSlider').addEventListener('input', () => {
            frameRateValue = parseInt(document.getElementById('pauseSpeedSlider').value);
            document.getElementById('startSpeedSlider').value = frameRateValue;
        });
    }

    function draw() {
        let gradient = drawingContext.createLinearGradient(0, 0, 0, height);
        gradient.addColorStop(0, '#4facfe');
        gradient.addColorStop(1, '#00f2fe');
        drawingContext.fillStyle = gradient;
        rect(0, 0, width, height);

        if (gameStarted && !paused && !gameOver) {
            frameRate(frameRateValue);
            board.show();
            currentPiece.show();
            currentPiece.update();
        } else if (gameStarted) {
            board.show();
            currentPiece.show();
        }

        document.getElementById('scoreDisplay').innerText = `得分:${score}`;

        if (gameOver) {
            textSize(32);
            textAlign(CENTER);
            fill(255, 50, 50);
            text("游戏结束", width/2, height/2);
            drawingContext.shadowBlur = 20;
            drawingContext.shadowColor = 'rgba(255, 0, 0, 0.5)';
        } else {
            drawingContext.shadowBlur = 0;
        }
    }

    function keyPressed() {
        if (keyCode === 32) {
            if (gameStarted && !gameOver) {
                paused = !paused;
                document.getElementById('pauseModal').style.display = paused ? 'flex' : 'none';
                document.getElementById('pauseModalTitle').innerText = '暂停';
                document.getElementById('resumeButton').style.display = 'inline-block';
            }
            return;
        }

        if (gameOver || paused || !gameStarted) return;

        if (keyCode === LEFT_ARROW) {
            currentPiece.move(-1);
        } else if (keyCode === RIGHT_ARROW) {
            currentPiece.move(1);
        } else if (keyCode === DOWN_ARROW) {
            currentPiece.dropToBottom();
        } else if (keyCode === UP_ARROW) {
            currentPiece.rotate();
        }
    }

    class Board {
        constructor(w, h) {
            this.width = w;
            this.height = h;
            this.grid = [];
            for (let i = 0; i < h; i++) {
                this.grid[i] = [];
                for (let j = 0; j < w; j++) {
                    this.grid[i][j] = 0;
                }
            }
        }

        show() {
            let cellWidth = width / this.width;
            let cellHeight = height / this.height;

            for (let i = 0; i < this.height; i++) {
                for (let j = 0; j < this.width; j++) {
                    if (this.grid[i][j] === 1) {
                        fill(0, 128, 255);
                        stroke(255);
                        strokeWeight(2);
                        drawingContext.shadowBlur = 10;
                        drawingContext.shadowColor = 'rgba(0, 128, 255, 0.5)';
                        rect(j * cellWidth, i * cellHeight, cellWidth, cellHeight, 5);
                        drawingContext.shadowBlur = 0;
                    }
                }
            }
        }

        addPiece(piece) {
            for (let i = 0; i < piece.shape.length; i++) {
                for (let j = 0; j < piece.shape[i].length; j++) {
                    if (piece.shape[i][j] === 1) {
                        let boardX = piece.x + j;
                        let boardY = piece.y + i;
                        if (boardY >= 0 && boardY < this.height && boardX >= 0 && boardX < this.width) {
                            this.grid[boardY][boardX] = 1;
                        }
                    }
                }
            }
            this.clearLines();
        }

        checkCollision(piece) {
            for (let i = 0; i < piece.shape.length; i++) {
                for (let j = 0; j < piece.shape[i].length; j++) {
                    if (piece.shape[i][j] === 1) {
                        let boardX = piece.x + j;
                        let boardY = piece.y + i;

                        if (boardY >= this.height) return true;
                        if (boardX < 0 || boardX >= this.width) return true;
                        if (boardY >= 0 && this.grid[boardY][boardX] === 1) return true;
                    }
                }
            }
            return false;
        }

        clearLines() {
            let linesCleared = 0;
            for (let i = this.height - 1; i >= 0; i--) {
                let full = true;
                for (let j = 0; j < this.width; j++) {
                    if (this.grid[i][j] === 0) {
                        full = false;
                        break;
                    }
                }
                if (full) {
                    this.grid.splice(i, 1);
                    this.grid.unshift(new Array(this.width).fill(0));
                    linesCleared++;
                    i++;
                }
            }
            score += linesCleared * 100;
        }
    }

    class Piece {
        constructor() {
            this.shapes = [
                [[1, 1, 1, 1]], // I
                [[1, 1], [1, 1]], // O
                [[1, 1, 1], [0, 1, 0]], // T
                [[1, 1, 1], [1, 0, 0]], // L
                [[1, 1, 1], [0, 0, 1]], // J
                [[1, 1, 0], [0, 1, 1]], // S
                [[0, 1, 1], [1, 1, 0]] // Z
            ];
            this.shape = random(this.shapes);
            this.x = floor(board.width / 2) - floor(this.shape[0].length / 2);
            this.y = -this.shape.length;
            this.colors = [
                [0, 255, 255], // I: 青色
                [255, 255, 0], // O: 黄色
                [128, 0, 128], // T: 紫色
                [255, 165, 0], // L: 橙色
                [0, 0, 255],   // J: 蓝色
                [0, 255, 0],   // S: 绿色
                [255, 0, 0]    // Z: 红色
            ];
            this.color = this.colors[this.shapes.indexOf(this.shape)];
        }

        show() {
            let cellWidth = width / board.width;
            let cellHeight = height / board.height;

            for (let i = 0; i < this.shape.length; i++) {
                for (let j = 0; j < this.shape[i].length; j++) {
                    if (this.shape[i][j] === 1) {
                        fill(this.color[0], this.color[1], this.color[2]);
                        stroke(255);
                        strokeWeight(2);
                        drawingContext.shadowBlur = 10;
                        drawingContext.shadowColor = `rgba(${this.color[0]}, ${this.color[1]}, ${this.color[2]}, 0.5)`;
                        rect((this.x + j) * cellWidth, (this.y + i) * cellHeight, cellWidth, cellHeight, 5);
                        drawingContext.shadowBlur = 0;
                    }
                }
            }
        }

        update() {
            let nextPiece = new Piece();
            Object.assign(nextPiece, this);
            nextPiece.y++;

            if (board.checkCollision(nextPiece)) {
                if (this.y < 0) {
                    gameOver = true;
                    document.getElementById('pauseModal').style.display = 'flex';
                    document.getElementById('pauseModalTitle').innerText = '游戏结束';
                    document.getElementById('resumeButton').style.display = 'none';
                } else {
                    board.addPiece(this);
                    currentPiece = new Piece();
                }
            } else {
                this.y++;
            }
        }

        move(dir) {
            let nextPiece = new Piece();
            Object.assign(nextPiece, this);
            nextPiece.x += dir;

            if (!board.checkCollision(nextPiece)) {
                this.x = nextPiece.x;
            }
        }

        rotate() {
            let nextPiece = new Piece();
            Object.assign(nextPiece, this);
            let newShape = [];

            for (let i = 0; i < this.shape[0].length; i++) {
                newShape[i] = [];
                for (let j = 0; j < this.shape.length; j++) {
                    newShape[i][j] = this.shape[this.shape.length - 1 - j][i];
                }
            }

            nextPiece.shape = newShape;

            if (!board.checkCollision(nextPiece)) {
                this.shape = newShape;
            }
        }

        dropToBottom() {
            let nextPiece = new Piece();
            Object.assign(nextPiece, this);

            while (!board.checkCollision(nextPiece)) {
                this.y = nextPiece.y;
                nextPiece.y++;
            }

            if (this.y < 0 && board.checkCollision(nextPiece)) {
                gameOver = true;
                document.getElementById('pauseModal').style.display = 'flex';
                document.getElementById('pauseModalTitle').innerText = '游戏结束';
                document.getElementById('resumeButton').style.display = 'none';
            } else {
                board.addPiece(this);
                currentPiece = new Piece();
            }
        }
    }
</script>
</body>
</html>

https://blog.csdn.net/qq_62223405/article/details/149267019?fromshare=blogdetail&sharetype=blogdetail&sharerId=149267019&sharerefer=PC&sharesource=AnalogElectronic&sharefrom=from_link

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐