claude俄罗斯方块源码

发布于 2025年5月29日

本文内容由AI生成并经过人工精选,不保证100%准确,请酌情参考使用

ClaudeAI

我来为你创建一个完整的俄罗斯方块游戏,使用HTML、CSS和JavaScript实现。我为你创建了一个完整的俄罗斯方块游戏!这个游戏包含了所有经典功能:

<!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 {
            margin: 0;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            font-family: 'Arial', sans-serif;
            color: white;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }

        .game-container {
            display: flex;
            gap: 30px;
            align-items: flex-start;
        }

        .game-board {
            border: 3px solid #fff;
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            background: #000;
        }

        .info-panel {
            background: rgba(255,255,255,0.1);
            backdrop-filter: blur(10px);
            border-radius: 15px;
            padding: 20px;
            min-width: 200px;
            box-shadow: 0 8px 25px rgba(0,0,0,0.2);
        }

        .score {
            font-size: 18px;
            margin-bottom: 10px;
            font-weight: bold;
        }

        .next-piece {
            margin-top: 20px;
        }

        .next-canvas {
            border: 2px solid rgba(255,255,255,0.3);
            border-radius: 8px;
            background: rgba(0,0,0,0.3);
        }

        .controls {
            margin-top: 20px;
            font-size: 14px;
            line-height: 1.6;
        }

        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.9);
            color: white;
            padding: 30px;
            border-radius: 15px;
            text-align: center;
            display: none;
            box-shadow: 0 15px 40px rgba(0,0,0,0.5);
        }

        .restart-btn {
            background: linear-gradient(45deg, #ff6b6b, #ee5a52);
            color: white;
            border: none;
            padding: 12px 25px;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            margin-top: 15px;
            transition: transform 0.2s;
        }

        .restart-btn:hover {
            transform: scale(1.05);
        }

        h1 {
            text-align: center;
            margin-bottom: 20px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
        }
    </style>
</head>
<body>
    <div>
        <h1>🎮 俄罗斯方块</h1>
        <div class="game-container">
            <canvas id="gameCanvas" class="game-board" width="300" height="600"></canvas>
            <div class="info-panel">
                <div class="score">得分: <span id="score">0</span></div>
                <div class="score">等级: <span id="level">1</span></div>
                <div class="score">行数: <span id="lines">0</span></div>
                <div class="next-piece">
                    <div>下一个:</div>
                    <canvas id="nextCanvas" class="next-canvas" width="80" height="80"></canvas>
                </div>
                <div class="controls">
                    <strong>控制:</strong><br>
                    ← → 移动<br>
                    ↓ 快速下降<br>
                    ↑ 旋转<br>
                    空格键 暂停
                </div>
            </div>
        </div>
        <div id="gameOver" class="game-over">
            <h2>游戏结束</h2>
            <p>最终得分: <span id="finalScore">0</span></p>
            <button class="restart-btn" onclick="restartGame()">重新开始</button>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const nextCanvas = document.getElementById('nextCanvas');
        const nextCtx = nextCanvas.getContext('2d');

        const BOARD_WIDTH = 10;
        const BOARD_HEIGHT = 20;
        const BLOCK_SIZE = 30;

        let board = Array(BOARD_HEIGHT).fill().map(() => Array(BOARD_WIDTH).fill(0));
        let score = 0;
        let level = 1;
        let lines = 0;
        let dropTime = 0;
        let dropInterval = 1000;
        let lastTime = 0;
        let gameRunning = true;
        let paused = false;

        // 方块形状定义
        const pieces = [
            { // I
                shape: [
                    [1, 1, 1, 1]
                ],
                color: '#00f5ff'
            },
            { // O
                shape: [
                    [1, 1],
                    [1, 1]
                ],
                color: '#ffff00'
            },
            { // T
                shape: [
                    [0, 1, 0],
                    [1, 1, 1]
                ],
                color: '#800080'
            },
            { // S
                shape: [
                    [0, 1, 1],
                    [1, 1, 0]
                ],
                color: '#00ff00'
            },
            { // Z
                shape: [
                    [1, 1, 0],
                    [0, 1, 1]
                ],
                color: '#ff0000'
            },
            { // J
                shape: [
                    [1, 0, 0],
                    [1, 1, 1]
                ],
                color: '#0000ff'
            },
            { // L
                shape: [
                    [0, 0, 1],
                    [1, 1, 1]
                ],
                color: '#ffa500'
            }
        ];

        let currentPiece = null;
        let nextPiece = null;

        function createPiece() {
            const piece = pieces[Math.floor(Math.random() * pieces.length)];
            return {
                shape: piece.shape,
                color: piece.color,
                x: Math.floor(BOARD_WIDTH / 2) - Math.floor(piece.shape[0].length / 2),
                y: 0
            };
        }

        function drawBlock(ctx, x, y, color) {
            ctx.fillStyle = color;
            ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
            ctx.strokeStyle = '#fff';
            ctx.lineWidth = 1;
            ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
        }

        function drawBoard() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制已放置的方块
            for (let y = 0; y < BOARD_HEIGHT; y++) {
                for (let x = 0; x < BOARD_WIDTH; x++) {
                    if (board[y][x]) {
                        drawBlock(ctx, x, y, board[y][x]);
                    }
                }
            }

            // 绘制当前方块
            if (currentPiece) {
                drawPiece(ctx, currentPiece);
            }
        }

        function drawPiece(context, piece) {
            piece.shape.forEach((row, dy) => {
                row.forEach((value, dx) => {
                    if (value) {
                        const x = piece.x + dx;
                        const y = piece.y + dy;
                        if (context === nextCtx) {
                            context.fillStyle = piece.color;
                            context.fillRect(dx * 20, dy * 20, 20, 20);
                            context.strokeStyle = '#fff';
                            context.strokeRect(dx * 20, dy * 20, 20, 20);
                        } else {
                            drawBlock(context, x, y, piece.color);
                        }
                    }
                });
            });
        }

        function isValidMove(piece, dx, dy) {
            for (let y = 0; y < piece.shape.length; y++) {
                for (let x = 0; x < piece.shape[y].length; x++) {
                    if (piece.shape[y][x]) {
                        const newX = piece.x + x + dx;
                        const newY = piece.y + y + dy;
                        
                        if (newX < 0 || newX >= BOARD_WIDTH || 
                            newY >= BOARD_HEIGHT ||
                            (newY >= 0 && board[newY][newX])) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placePiece() {
            currentPiece.shape.forEach((row, dy) => {
                row.forEach((value, dx) => {
                    if (value) {
                        const x = currentPiece.x + dx;
                        const y = currentPiece.y + dy;
                        if (y >= 0) {
                            board[y][x] = currentPiece.color;
                        }
                    }
                });
            });

            clearLines();
            currentPiece = nextPiece;
            nextPiece = createPiece();
            
            if (!isValidMove(currentPiece, 0, 0)) {
                gameOver();
            }
        }

        function clearLines() {
            let linesCleared = 0;
            for (let y = BOARD_HEIGHT - 1; y >= 0; y--) {
                if (board[y].every(cell => cell !== 0)) {
                    board.splice(y, 1);
                    board.unshift(Array(BOARD_WIDTH).fill(0));
                    linesCleared++;
                    y++; // 检查同一行
                }
            }

            if (linesCleared > 0) {
                lines += linesCleared;
                score += linesCleared * 100 * level;
                level = Math.floor(lines / 10) + 1;
                dropInterval = Math.max(50, 1000 - (level - 1) * 100);
                updateDisplay();
            }
        }

        function rotatePiece() {
            const rotated = currentPiece.shape[0].map((_, i) =>
                currentPiece.shape.map(row => row[i]).reverse()
            );
            
            const originalShape = currentPiece.shape;
            currentPiece.shape = rotated;
            
            if (!isValidMove(currentPiece, 0, 0)) {
                currentPiece.shape = originalShape;
            }
        }

        function updateDisplay() {
            document.getElementById('score').textContent = score;
            document.getElementById('level').textContent = level;
            document.getElementById('lines').textContent = lines;
            
            nextCtx.clearRect(0, 0, nextCanvas.width, nextCanvas.height);
            if (nextPiece) {
                drawPiece(nextCtx, nextPiece);
            }
        }

        function gameOver() {
            gameRunning = false;
            document.getElementById('finalScore').textContent = score;
            document.getElementById('gameOver').style.display = 'block';
        }

        function restartGame() {
            board = Array(BOARD_HEIGHT).fill().map(() => Array(BOARD_WIDTH).fill(0));
            score = 0;
            level = 1;
            lines = 0;
            dropInterval = 1000;
            gameRunning = true;
            paused = false;
            currentPiece = createPiece();
            nextPiece = createPiece();
            document.getElementById('gameOver').style.display = 'none';
            updateDisplay();
            gameLoop();
        }

        function gameLoop(time = 0) {
            if (!gameRunning || paused) return;

            const deltaTime = time - lastTime;
            lastTime = time;
            dropTime += deltaTime;

            if (dropTime > dropInterval) {
                if (isValidMove(currentPiece, 0, 1)) {
                    currentPiece.y++;
                } else {
                    placePiece();
                }
                dropTime = 0;
            }

            drawBoard();
            requestAnimationFrame(gameLoop);
        }

        // 键盘控制
        document.addEventListener('keydown', (e) => {
            if (!gameRunning || paused) return;

            switch(e.key) {
                case 'ArrowLeft':
                    if (isValidMove(currentPiece, -1, 0)) {
                        currentPiece.x--;
                    }
                    break;
                case 'ArrowRight':
                    if (isValidMove(currentPiece, 1, 0)) {
                        currentPiece.x++;
                    }
                    break;
                case 'ArrowDown':
                    if (isValidMove(currentPiece, 0, 1)) {
                        currentPiece.y++;
                        score += 1;
                        updateDisplay();
                    }
                    break;
                case 'ArrowUp':
                    rotatePiece();
                    break;
                case ' ':
                    paused = !paused;
                    if (!paused) gameLoop();
                    break;
            }
            e.preventDefault();
        });

        // 初始化游戏
        currentPiece = createPiece();
        nextPiece = createPiece();
        updateDisplay();
        gameLoop();
    </script>
</body>
</html>

游戏特色:

  • 7种经典方块形状(I、O、T、S、Z、J、L)
  • 完整的游戏逻辑:旋转、移动、消行
  • 得分系统和等级提升
  • 下一个方块预览
  • 暂停功能
  • 游戏结束和重新开始

操作说明:

  • ← → 键:左右移动方块
  • ↓ 键:加速下降
  • ↑ 键:旋转方块
  • 空格键:暂停/继续游戏

游戏机制:

  • 消除一行得100分×当前等级
  • 每消除10行升一级
  • 等级越高,方块下降速度越快
  • 方块堆到顶部游戏结束

界面采用了现代化的设计,包括渐变背景、毛玻璃效果和平滑动画。游戏完全可玩,你可以立即开始享受经典的俄罗斯方块游戏体验!