源码在效果图后面 五个按钮控制
效果图
源代码
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>俄罗斯方块游戏</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh;font-family: 'Arial', sans-serif;background-color: #f0f0f0;}canvas {border: 2px solid #333;border-radius: 10px;box-shadow: 2px 2px 12px rgba(0, 0, 0, 0.5);background-color: #fff;}#controls {margin-left: 20px;display: flex;flex-direction: column;gap: 10px;}button {padding: 10px 15px;border: none;border-radius: 5px;background-color: #007bff;color: #fff;cursor: pointer;box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);transition: background-color 0.3s;}button:hover {background-color: #0056b3;}</style>
</head>
<body><canvas id="board" width="300" height="600"></canvas><div id="controls"><button id="left">左</button><button id="right">右</button><button id="down">下</button><button id="rotate">旋转</button><button id="start">开始</button></div><script>const canvas = document.getElementById('board');const ctx = canvas.getContext('2d');const cols = 10;const rows = 20;const blockSize = 30;const colors = [null,'cyan','blue','orange','yellow','green','purple','red',];const pieces = [[[1, 1, 1, 1]], // I[[1, 1, 1], [0, 1, 0]], // T[[1, 1, 0], [0, 1, 1]], // Z[[0, 1, 1], [1, 1, 0]], // S[[1, 1], [1, 1]], // O[[1, 1, 1], [1, 0, 0]], // L[[1, 1, 1], [0, 0, 1]], // J];let board = Array.from({ length: rows }, () => Array(cols).fill(0));let currentPiece;let currentPosition;let dropInterval;let gameOver = false;function drawBoard() {ctx.clearRect(0, 0, canvas.width, canvas.height);for (let r = 0; r < rows; r++) {for (let c = 0; c < cols; c++) {if (board[r][c]) {ctx.fillStyle = colors[board[r][c]];ctx.fillRect(c * blockSize, r * blockSize, blockSize, blockSize);ctx.strokeStyle = '#333';ctx.strokeRect(c * blockSize, r * blockSize, blockSize, blockSize);}}}drawPiece();}function drawPiece() {ctx.fillStyle = colors[currentPiece.color];currentPiece.shape.forEach((row, r) => {row.forEach((value, c) => {if (value) {ctx.fillRect((currentPosition.x + c) * blockSize, (currentPosition.y + r) * blockSize, blockSize, blockSize);ctx.strokeRect((currentPosition.x + c) * blockSize, (currentPosition.y + r) * blockSize, blockSize, blockSize);}});});}function rotate(piece) {return piece[0].map((_, index) => piece.map(row => row[index])).reverse();}function collision(offsetX = 0, offsetY = 0, piece = currentPiece) {return piece.shape.some((row, r) => {return row.some((value, c) => {if (value) {const newX = currentPosition.x + c + offsetX;const newY = currentPosition.y + r + offsetY;return (newX < 0 ||newX >= cols ||newY >= rows ||(newY >= 0 && board[newY][newX] !== 0));}return false;});});}function merge() {currentPiece.shape.forEach((row, r) => {row.forEach((value, c) => {if (value) {board[currentPosition.y + r][currentPosition.x + c] = currentPiece.color;}});});clearRows();}function clearRows() {for (let r = rows - 1; r >= 0; r--) {if (board[r].every(cell => cell !== 0)) {board.splice(r, 1);board.unshift(Array(cols).fill(0));}}}function spawnPiece() {const index = Math.floor(Math.random() * pieces.length);currentPiece = {shape: pieces[index],color: index + 1,};currentPosition = { x: Math.floor(cols / 2) - 1, y: 0 };if (collision(0, 0)) {gameOver = true;}}function drop() {if (!gameOver) {if (!collision(0, 1)) {currentPosition.y++;} else {merge();spawnPiece();}drawBoard();} else {clearInterval(dropInterval);alert('游戏结束!');}}function startGame() {board = Array.from({ length: rows }, () => Array(cols).fill(0));currentPiece = null;currentPosition = null;gameOver = false;spawnPiece();drawBoard();dropInterval = setInterval(drop, 1000);}document.getElementById('left').addEventListener('click', () => {if (!collision(-1, 0)) currentPosition.x--;drawBoard();});document.getElementById('right').addEventListener('click', () => {if (!collision(1, 0)) currentPosition.x++;drawBoard();});document.getElementById('down').addEventListener('click', () => {drop();});document.getElementById('rotate').addEventListener('click', () => {const rotated = rotate(currentPiece.shape);if (!collision(0, 0, { shape: rotated, color: currentPiece.color })) {currentPiece.shape = rotated;}drawBoard();});document.getElementById('start').addEventListener('click', startGame);drawBoard();</script>
</body>
</html>