使用js和canvas、html实现简单的俄罗斯方块小游戏

时间:2024-10-25 10:31:21
// 获取画布和上下文 const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const scoreDisplay = document.getElementById('score'); const startButton = document.getElementById('start-button'); // 游戏板的宽度和高度 const boardWidth = 10; const boardHeight = 20; const blockSize = 30; // 初始化游戏板、当前方块、得分和游戏间隔 let board = []; let currentPiece = null; let score = 0; let gameInterval = null; // 颜色数组 const colors = [ 'cyan', 'blue', 'orange', 'yellow', 'green', 'purple', 'red' ]; // 方块形状数组 const pieces = [ [[1, 1, 1, 1]], // I [[1, 1, 1], [0, 1, 0]], // T [[1, 1, 1], [1, 0, 0]], // L [[1, 1, 1], [0, 0, 1]], // J [[1, 1], [1, 1]], // O [[0, 1, 1], [1, 1, 0]], // S [[1, 1, 0], [0, 1, 1]] // Z ]; // 方块类 class Piece { constructor(tetromino) { this.tetromino = tetromino; // 方块形状 this.color = colors[Math.floor(Math.random() * colors.length)]; // 随机颜色 this.x = 3; // 初始位置 this.y = -2; // 初始位置 } // 旋转方块 rotate() { const newTetromino = this.tetromino[0].map((_, i) => this.tetromino.map(row => row[i])).reverse(); if (!this.collision(newTetromino, this.x, this.y)) { this.tetromino = newTetromino; } } // 检测碰撞 collision(tetromino, x, y) { for (let row = 0; row < tetromino.length; row++) { for (let col = 0; col < tetromino[row].length; col++) { if (tetromino[row][col] && (board[y + row] && board[y + row][x + col] || x + col < 0 || x + col >= boardWidth || y + row >= boardHeight)) { return true; } } } return false; } // 向下移动 moveDown() { if (!this.collision(this.tetromino, this.x, this.y + 1)) { this.y++; } else { this.lockPiece(); // 锁定方块 clearLines(); // 清除满行 if (this.y <= 0) { // 检查是否触顶 gameOver(); } else { newPiece(); // 生成新方块 } } } // 向左移动 moveLeft() { if (!this.collision(this.tetromino, this.x - 1, this.y)) { this.x--; } } // 向右移动 moveRight() { if (!this.collision(this.tetromino, this.x + 1, this.y)) { this.x++; } } // 锁定方块到游戏板 lockPiece() { for (let row = 0; row < this.tetromino.length; row++) { for (let col = 0; col < this.tetromino[row].length; col++) { if (this.tetromino[row][col]) { board[this.y + row][this.x + col] = this.color; } } } } } // 生成新方块 function newPiece() { const randomPiece = pieces[Math.floor(Math.random() * pieces.length)]; currentPiece = new Piece(randomPiece); } // 绘制游戏板 function drawBoard() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布 for (let row = 0; row < boardHeight; row++) { for (let col = 0; col < boardWidth; col++) { if (board[row][col]) { ctx.fillStyle = board[row][col]; // 设置颜色 ctx.fillRect(col * blockSize, row * blockSize, blockSize, blockSize); // 绘制方块 } } } if (currentPiece) { for (let row = 0; row < currentPiece.tetromino.length; row++) { for (let col = 0; col < currentPiece.tetromino[row].length; col++) { if (currentPiece.tetromino[row][col]) { ctx.fillStyle = currentPiece.color; // 设置颜色 ctx.fillRect((currentPiece.x + col) * blockSize, (currentPiece.y + row) * blockSize, blockSize, blockSize); // 绘制方块 } } } } } // 清除满行 function clearLines() { for (let row = boardHeight - 1; row >= 0; row--) { if (board[row].every(cell => cell !== 0)) { // 检查行是否满 board.splice(row, 1); // 删除满行 board.unshift(Array(boardWidth).fill(0)); // 添加空行 score += 10; // 增加得分 scoreDisplay.textContent = `得分: ${score}`; // 更新得分显示 } } } // 游戏循环 function gameLoop() { if (currentPiece) { currentPiece.moveDown(); // 移动方块 } drawBoard(); // 绘制游戏板 } // 开始游戏 function startGame() { if (gameInterval) { clearInterval(gameInterval); // 清除之前的定时器 } board = Array.from({ length: boardHeight }, () => Array(boardWidth).fill(0)); // 重置游戏板 score = 0; // 重置得分 scoreDisplay.textContent = `得分: ${score}`; // 更新得分显示 newPiece(); // 生成新方块 gameInterval = setInterval(gameLoop, 300); // 启动游戏循环 document.addEventListener('keydown', handleKeyPress); // 监听键盘事件 } // 处理键盘事件 function handleKeyPress(event) { if (currentPiece) { switch (event.key) { case 'ArrowDown': currentPiece.moveDown(); // 向下移动 break; case 'ArrowLeft': currentPiece.moveLeft(); // 向左移动 break; case 'ArrowRight': currentPiece.moveRight(); // 向右移动 break; case 'ArrowUp': currentPiece.rotate(); // 旋转方块 break; } } } // 游戏结束 function gameOver() { clearInterval(gameInterval); // 清除游戏循环 document.removeEventListener('keydown', handleKeyPress); // 移除键盘事件监听 alert('游戏结束!'); } // 绑定开始游戏按钮的点击事件 startButton.addEventListener('click', startGame);