Let's go

俄罗斯方块

<!DOCTYPE html>
<html>
<head>
    <title>简易俄罗斯方块</title>
    <style>
        canvas {
            border: 2px solid #333;
        }
        body {
            display: flex;
            justify-content: center;
            background-color: #f0f0f0;
        }
    </style>
</head>
<body>
    <canvas id="game" width="300" height="600"></canvas>

<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const BLOCK_SIZE = 30;
const COLS = 10;
const ROWS = 20;

// 游戏板
let board = Array(ROWS).fill().map(() => Array(COLS).fill(0));

// 方块形状
const SHAPES = [
    [[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
    [[1,1,0],[0,1,1]], // S
    [[0,1,1],[1,1,0]]  // Z
];

let currentPiece = null;
let currentX = 0;
let currentY = 0;
let score = 0;

// 创建新方块
function newPiece() {
    currentPiece = SHAPES[Math.floor(Math.random()*SHAPES.length)];
    currentX = Math.floor(COLS/2) - Math.floor(currentPiece[0].length/2);
    currentY = 0;
    
    if (!canMove(0, 0)) {
        alert("游戏结束!得分:" + score);
        resetGame();
    }
}

// 重置游戏
function resetGame() {
    board = Array(ROWS).fill().map(() => Array(COLS).fill(0));
    score = 0;
    newPiece();
}

// 检查能否移动
function canMove(offsetX, offsetY) {
    return currentPiece.every((row, dy) => 
        row.every((cell, dx) => {
            let x = currentX + dx + offsetX;
            let y = currentY + dy + offsetY;
            return !cell || (x >= 0 && x < COLS && y < ROWS && !board[y]?.[x]);
        })
    );
}

// 固定方块到游戏板
function lockPiece() {
    currentPiece.forEach((row, dy) => {
        row.forEach((cell, dx) => {
            if (cell) board[currentY + dy][currentX + dx] = 1;
        });
    });
    checkLines();
    newPiece();
}

// 消除满行
function checkLines() {
    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) {
        score += lines * 100;
    }
}

// 绘制游戏
function draw() {
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 绘制游戏板
    board.forEach((row, y) => {
        row.forEach((cell, x) => {
            if (cell) {
                ctx.fillStyle = '#f00';
                ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE-1, BLOCK_SIZE-1);
            }
        });
    });

    // 绘制当前方块
    if (currentPiece) {
        ctx.fillStyle = '#0f0';
        currentPiece.forEach((row, dy) => {
            row.forEach((cell, dx) => {
                if (cell) {
                    ctx.fillRect(
                        (currentX + dx) * BLOCK_SIZE,
                        (currentY + dy) * BLOCK_SIZE,
                        BLOCK_SIZE-1, BLOCK_SIZE-1
                    );
                }
            });
        });
    }

    // 显示分数
    ctx.fillStyle = '#fff';
    ctx.font = '20px Arial';
    ctx.fillText('得分: ' + score, 10, 30);
}

// 游戏循环
function update() {
    if (canMove(0, 1)) {
        currentY++;
    } else {
        lockPiece();
    }
    draw();
}

// 控制
document.addEventListener('keydown', event => {
    switch(event.keyCode) {
        case 37: //
            if (canMove(-1, 0)) currentX--;
            break;
        case 39: //
            if (canMove(1, 0)) currentX++;
            break;
        case 40: //
            if (canMove(0, 1)) currentY++;
            break;
        case 38: // 上(旋转)
            const rotated = currentPiece[0].map((_, i) =>
                currentPiece.map(row => row[i]).reverse()
            );
            const previous = currentPiece;
            currentPiece = rotated;
            if (!canMove(0, 0)) currentPiece = previous;
            break;
    }
    draw();
});

// 开始游戏
newPiece();
setInterval(update, 1000);
</script>
</body>
</html>

1

posted @ 2025-04-09 08:28  chenze  阅读(8)  评论(0)    收藏  举报
有事您Q我