这里是一个完整的H5俄罗斯方块游戏,使用了 HTML + CSS + JavaScript (原生) 实现,支持基本的俄罗斯方块玩法,如:
✅ 方块自动下落
✅ 方向键控制移动、旋转、加速下落
✅ 方块堆叠、消行
✅ 计分系统
在 canvas 上绘制游戏,并使用 requestAnimationFrame
进行流畅的动画渲染。下面是完整的代码:
const canvas = document.getElementById("tetris");
const ctx = canvas.getContext("2d");
const ROWS = 20;
const COLS = 10;
const SIZE = 30; // 每个格子的大小
// 定义俄罗斯方块的形状
const SHAPES = [
[[1, 1, 1, 1]], // I
[[1, 1], [1, 1]], // O
[[0, 1, 0], [1, 1, 1]], // T
[[1, 1, 0], [0, 1, 1]], // S
[[0, 1, 1], [1, 1, 0]], // Z
[[1, 0, 0], [1, 1, 1]], // J
[[0, 0, 1], [1, 1, 1]], // L
];
// 颜色数组
const COLORS = ["cyan", "yellow", "purple", "green", "red", "blue", "orange"];
let board = Array.from({ length: ROWS }, () => Array(COLS).fill(0));
let currentPiece;
let gameOver = false;
let score = 0;
// 生成新方块
function newPiece() {
const index = Math.floor(Math.random() * SHAPES.length);
currentPiece = {
shape: SHAPES[index],
color: COLORS[index],
row: 0,
col: Math.floor(COLS / 2) - 1,
};
}
newPiece();
// 画一个方块
function drawBlock(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x * SIZE, y * SIZE, SIZE, SIZE);
ctx.strokeStyle = "black";
ctx.strokeRect(x * SIZE, y * SIZE, SIZE, SIZE);
}
// 画游戏面板
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]) {
drawBlock(c, r, board[r][c]);
}
}
}
drawPiece();
}
// 画当前下落的方块
function drawPiece() {
currentPiece.shape.forEach((row, r) => {
row.forEach((cell, c) => {
if (cell) {
drawBlock(currentPiece.col + c, currentPiece.row + r, currentPiece.color);
}
});
});
}
// 碰撞检测
function isValidMove(offsetRow, offsetCol, shape) {
return shape.every((row, r) =>
row.every((cell, c) => {
if (!cell) return true;
let newRow = currentPiece.row + r + offsetRow;
let newCol = currentPiece.col + c + offsetCol;
return (
newRow >= 0 &&
newRow < ROWS &&
newCol >= 0 &&
newCol < COLS &&
!board[newRow][newCol]
);
})
);
}
// 移动方块
function movePiece(offsetRow, offsetCol) {
if (isValidMove(offsetRow, offsetCol, currentPiece.shape)) {
currentPiece.row += offsetRow;
currentPiece.col += offsetCol;
}
}
// 旋转方块
function rotatePiece() {
const rotated = currentPiece.shape[0].map((_, c) =>
currentPiece.shape.map(row => row[c]).reverse()
);
if (isValidMove(0, 0, rotated)) {
currentPiece.shape = rotated;
}
}
// 触底逻辑
function placePiece() {
currentPiece.shape.forEach((row, r) => {
row.forEach((cell, c) => {
if (cell) {
board[currentPiece.row + r][currentPiece.col + c] = currentPiece.color;
}
});
});
clearRows();
newPiece();
if (!isValidMove(0, 0, currentPiece.shape)) {
gameOver = true;
}
}
// 消行逻辑
function clearRows() {
board = board.filter(row => row.some(cell => !cell));
while (board.length < ROWS) {
board.unshift(Array(COLS).fill(0));
score += 10;
}
}
// 游戏循环
function update() {
if (!gameOver) {
if (isValidMove(1, 0, currentPiece.shape)) {
movePiece(1, 0);
} else {
placePiece();
}
drawBoard();
document.getElementById("score").innerText = score;
setTimeout(update, 500);
} else {
alert("游戏结束!");
}
}
update();
// 监听键盘事件
document.addEventListener("keydown", (event) => {
if (gameOver) return;
if (event.key === "ArrowLeft") movePiece(0, -1);
if (event.key === "ArrowRight") movePiece(0, 1);
if (event.key === "ArrowDown") movePiece(1, 0);
if (event.key === "ArrowUp") rotatePiece();
drawBoard();
});
说明:
- 使用
canvas
进行绘制 - 方块随机生成并自动下落
- 方向键:
- 左/右键 移动
- 下键 加速下落
- 上键 旋转
- 触底后自动消行并累加得分
- 游戏结束提示
alert("游戏结束!")
你可以直接将这段代码放入 index.html
页面,并配合 <canvas>
运行。