js实现俄罗斯方块
实现俄罗斯方块的基本思路
俄罗斯方块的核心逻辑包括方块生成、移动、旋转、碰撞检测和消除行。使用JavaScript实现时,需结合HTML5的Canvas或DOM操作来渲染游戏界面。
游戏初始化
创建画布并定义游戏区域尺寸,通常以网格形式表示。每个方块占据一个网格单元。
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 30;
const rows = 20;
const cols = 10;
方块定义与生成
定义七种经典方块(I、J、L、O、S、T、Z)的形状及颜色。使用二维数组表示每种方块的形态。
const shapes = [
[[1, 1, 1, 1]], // I
[[1, 0, 0], [1, 1, 1]], // J
[[0, 0, 1], [1, 1, 1]], // L
[[1, 1], [1, 1]], // O
[[0, 1, 1], [1, 1, 0]], // S
[[0, 1, 0], [1, 1, 1]], // T
[[1, 1, 0], [0, 1, 1]] // Z
];
随机生成方块并设置初始位置:
function newPiece() {
const id = Math.floor(Math.random() * shapes.length);
return {
shape: shapes[id],
x: Math.floor(cols / 2) - 1,
y: 0,
color: colors[id]
};
}
游戏主循环
使用requestAnimationFrame实现游戏循环,控制方块下落速度。
function gameLoop() {
dropPiece();
draw();
if (!gameOver) requestAnimationFrame(gameLoop);
}
方块移动与旋转
处理键盘事件实现左右移动、加速下落和旋转:
document.addEventListener('keydown', event => {
if (event.key === 'ArrowLeft') move(-1);
if (event.key === 'ArrowRight') move(1);
if (event.key === 'ArrowDown') drop();
if (event.key === 'ArrowUp') rotate();
});
旋转算法通过矩阵转置实现:
function rotate() {
const rotated = piece.shape[0].map((_, i) =>
piece.shape.map(row => row[i]).reverse()
);
if (!collision(rotated)) piece.shape = rotated;
}
碰撞检测
检查方块是否超出边界或与已固定的方块重叠:
function collision(shape, offsetX = 0, offsetY = 0) {
for (let y = 0; y < shape.length; y++) {
for (let x = 0; x < shape[y].length; x++) {
if (shape[y][x] === 0) continue;
const newX = piece.x + x + offsetX;
const newY = piece.y + y + offsetY;
if (newX < 0 || newX >= cols || newY >= rows) return true;
if (newY < 0) continue;
if (board[newY][newX]) return true;
}
}
return false;
}
消除行与计分
扫描完整行并消除,同时更新分数:
function clearLines() {
let lines = 0;
for (let y = rows - 1; y >= 0; y--) {
if (board[y].every(cell => cell)) {
board.splice(y, 1);
board.unshift(Array(cols).fill(0));
lines++;
y++;
}
}
if (lines > 0) score += lines * 10;
}
渲染游戏界面
绘制当前方块和已固定的方块:
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBoard();
drawPiece();
}
function drawPiece() {
piece.shape.forEach((row, y) => {
row.forEach((value, x) => {
if (value) {
ctx.fillStyle = piece.color;
ctx.fillRect(
(piece.x + x) * gridSize,
(piece.y + y) * gridSize,
gridSize, gridSize
);
}
});
});
}
完整实现建议
- 初始化画布和游戏状态(棋盘、当前方块、分数等)
- 实现方块生成、移动、旋转和碰撞检测
- 添加游戏循环控制方块自动下落
- 处理键盘输入实现玩家控制
- 实现行消除逻辑和分数计算
- 添加游戏结束条件检测
示例代码结构:
// 初始化
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// ...其他常量定义...
let board = Array(rows).fill().map(() => Array(cols).fill(0));
let piece = newPiece();
let score = 0;
let gameOver = false;
// 游戏主逻辑
function dropPiece() {
if (!collision(piece.shape, 0, 1)) {
piece.y++;
} else {
mergePiece();
clearLines();
piece = newPiece();
if (collision(piece.shape)) gameOver = true;
}
}
// 渲染和启动
function draw() { /* ... */ }
function gameLoop() { /* ... */ }
gameLoop();






