俄罗斯方块又一版edit icon

作者:
用户fkxIv10
Fork(复制)
下载
嵌入
BUG反馈
index.html
现在支持上传本地图片了!
index.html
            
            <!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 {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #1a1a2e, #16213e);
            color: #fff;
        }
        
        .game-container {
            display: flex;
            gap: 20px;
        }
        
        #game-board {
            border: 2px solid #4cc9f0;
            background-color: #0f3460;
            box-shadow: 0 0 20px rgba(76, 201, 240, 0.5);
        }
        
        .info-panel {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        
        .next-piece-container {
            width: 120px;
            height: 120px;
            border: 2px solid #4cc9f0;
            background-color: #0f3460;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 0 10px rgba(76, 201, 240, 0.3);
        }
        
        #next-piece {
            display: grid;
            grid-template-columns: repeat(4, 20px);
            grid-template-rows: repeat(4, 20px);
        }
        
        .stats {
            background-color: #0f3460;
            padding: 15px;
            border-radius: 5px;
            border: 2px solid #4cc9f0;
            box-shadow: 0 0 10px rgba(76, 201, 240, 0.3);
        }
        
        .controls {
            background-color: #0f3460;
            padding: 15px;
            border-radius: 5px;
            border: 2px solid #4cc9f0;
            box-shadow: 0 0 10px rgba(76, 201, 240, 0.3);
        }
        
        button {
            background-color: #4361ee;
            color: white;
            border: none;
            padding: 10px 15px;
            margin: 5px;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        button:hover {
            background-color: #3a56d4;
            transform: translateY(-2px);
        }
        
        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(15, 52, 96, 0.95);
            padding: 30px;
            border-radius: 10px;
            text-align: center;
            border: 2px solid #f72585;
            box-shadow: 0 0 30px rgba(247, 37, 133, 0.7);
        }
        
        .game-over h2 {
            color: #f72585;
            margin-top: 0;
        }
        
        .cell {
            width: 20px;
            height: 20px;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .I { background-color: #00f0f0; }
        .J { background-color: #0000f0; }
        .L { background-color: #f0a000; }
        .O { background-color: #f0f000; }
        .S { background-color: #00f000; }
        .T { background-color: #a000f0; }
        .Z { background-color: #f00000; }
        
        .grid-cell {
            background-color: #1b3a61;
        }
        
        .instructions {
            margin-top: 20px;
            font-size: 14px;
            line-height: 1.5;
            color: #a9d6e5;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <canvas id="game-board" width="300" height="600"></canvas>
        <div class="info-panel">
            <div class="next-piece-container">
                <canvas id="next-piece" width="80" height="80"></canvas>
            </div>
            <div class="stats">
                <h3>得分: <span id="score">0</span></h3>
                <h3>等级: <span id="level">1</span></h3>
                <h3>消除行数: <span id="lines">0</span></h3>
            </div>
            <div class="controls">
                <button id="start-btn">开始/暂停</button>
                <button id="reset-btn">重置</button>
                <div class="instructions">
                    <p>← → 移动</p>
                    <p>↑ 旋转</p>
                    <p>↓ 加速下降</p>
                    <p>空格 瞬间下落</p>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 游戏常量
        const COLS = 10;
        const ROWS = 20;
        const BLOCK_SIZE = 30;
        const COLORS = [
            null,
            '#00f0f0', // I
            '#0000f0', // J
            '#f0a000', // L
            '#f0f000', // O
            '#00f000', // S
            '#a000f0', // T
            '#f00000'  // Z
        ];
        
        // 方块形状
        const SHAPES = [
            null,
            [[0,0,0,0], [1,1,1,1], [0,0,0,0], [0,0,0,0]], // I
            [[1,0,0], [1,1,1], [0,0,0]],                   // J
            [[0,0,1], [1,1,1], [0,0,0]],                   // L
            [[1,1], [1,1]],                                // O
            [[0,1,1], [1,1,0], [0,0,0]],                   // S
            [[0,1,0], [1,1,1], [0,0,0]],                   // T
            [[1,1,0], [0,1,1], [0,0,0]]                    // Z
        ];
        
        // 游戏变量
        let canvas = document.getElementById('game-board');
        let ctx = canvas.getContext('2d');
        let nextCanvas = document.getElementById('next-piece');
        let nextCtx = nextCanvas.getContext('2d');
        let scoreElement = document.getElementById('score');
        let levelElement = document.getElementById('level');
        let linesElement = document.getElementById('lines');
        let startButton = document.getElementById('start-btn');
        let resetButton = document.getElementById('reset-btn');
        
        let board = [];
        let score = 0;
        let level = 1;
        let lines = 0;
        let gameOver = false;
        let isPaused = false;
        let dropCounter = 0;
        let dropInterval = 1000;
        let lastTime = 0;
        let currentPiece = null;
        let nextPiece = null;
        
        // 初始化游戏板
        function createBoard() {
            return Array.from(Array(ROWS), () => Array(COLS).fill(0));
        }
        
        // 创建随机方块
        function createPiece() {
            const rand = Math.floor(Math.random() * 7) + 1;
            return {
                shape: SHAPES[rand],
                color: COLORS[rand],
                pos: {x: Math.floor(COLS / 2) - 1, y: 0}
            };
        }
        
        // 绘制单个方块
        function drawBlock(x, y, color) {
            ctx.fillStyle = color;
            ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
            
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
            ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
            
            // 添加3D效果
            ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
            ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, 4, BLOCK_SIZE);
            ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, 4);
        }
        
        // 绘制下一个方块
        function drawNextPiece() {
            nextCtx.clearRect(0, 0, nextCanvas.width, nextCanvas.height);
            
            if (!nextPiece) return;
            
            const shape = nextPiece.shape;
            const offsetX = (4 - shape[0].length) / 2;
            const offsetY = (4 - shape.length) / 2;
            
            for (let y = 0; y < shape.length; y++) {
                for (let x = 0; x < shape[y].length; x++) {
                    if (shape[y][x]) {
                        nextCtx.fillStyle = nextPiece.color;
                        nextCtx.fillRect(
                            (offsetX + x) * 20, 
                            (offsetY + y) * 20, 
                            20, 20
                        );
                        
                        nextCtx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
                        nextCtx.strokeRect(
                            (offsetX + x) * 20, 
                            (offsetY + y) * 20, 
                            20, 20
                        );
                    }
                }
            }
        }
        
        // 绘制游戏板
        function drawBoard() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格背景
            for (let y = 0; y < ROWS; y++) {
                for (let x = 0; x < COLS; x++) {
                    if (board[y][x]) {
                        drawBlock(x, y, board[y][x]);
                    } else {
                        ctx.fillStyle = '#1b3a61';
                        ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                        
                        ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
                        ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
                    }
                }
            }
            
            // 绘制当前方块
            if (currentPiece) {
                const shape = currentPiece.shape;
                for (let y = 0; y < shape.length; y++) {
                    for (let x = 0; x < shape[y].length; x++) {
                        if (shape[y][x]) {
                            drawBlock(
                                currentPiece.pos.x + x, 
                                currentPiece.pos.y + y, 
                                currentPiece.color
                            );
                        }
                    }
                }
            }
        }
        
        // 检查碰撞
        function collision(piece, board, offset = {}) {
            const pos = piece.pos;
            const shape = piece.shape;
            const offsetX = offset.x || 0;
            const offsetY = offset.y || 0;
            
            for (let y = 0; y < shape.length; y++) {
                for (let x = 0; x < shape[y].length; x++) {
                    if (shape[y][x] !== 0) {
                        const newX = pos.x + x + offsetX;
                        const newY = pos.y + y + offsetY;
                        
                        if (
                            newX < 0 || 
                            newX >= COLS || 
                            newY >= ROWS ||
                            (newY >= 0 && board[newY][newX])
                        ) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        
        // 合并方块到游戏板
        function mergePiece() {
            const shape = currentPiece.shape;
            for (let y = 0; y < shape.length; y++) {
                for (let x = 0; x < shape[y].length; x++) {
                    if (shape[y][x]) {
                        const boardY = currentPiece.pos.y + y;
                        const boardX = currentPiece.pos.x + x;
                        if (boardY >= 0) {
                            board[boardY][boardX] = currentPiece.color;
                        }
                    }
                }
            }
        }
        
        // 旋转方块
        function rotatePiece() {
            const originalShape = currentPiece.shape;
            const rows = originalShape.length;
            const cols = originalShape[0].length;
            
            // 创建新数组来存储旋转后的形状
            const rotated = Array.from({ length: cols }, () => Array(rows).fill(0));
            
            for (let y = 0; y < rows; y++) {
                for (let x = 0; x < cols; x++) {
                    rotated[x][rows - 1 - y] = originalShape[y][x];
                }
            }
            
            // 检查旋转后是否有碰撞
            const originalPiece = currentPiece.shape;
            currentPiece.shape = rotated;
            
            if (collision(currentPiece, board)) {
                // 如果有碰撞,恢复原形状
                currentPiece.shape = originalPiece;
            }
        }
        
        // 清除完整行
        function clearLines() {
            let linesCleared = 0;
            
            outer: for (let y = ROWS - 1; y >= 0; y--) {
                for (let x = 0; x < COLS; x++) {
                    if (board[y][x] === 0) {
                        continue outer;
                    }
                }
                
                // 移除这一行
                const row = board.splice(y, 1)[0].fill(0);
                board.unshift(row);
                linesCleared++;
                y++; // 重新检查同一行(因为上面移除了)
            }
            
            if (linesCleared > 0) {
                // 更新分数
                const points = [40, 100, 300, 1200]; // 不同行数的得分
                score += points[linesCleared - 1] * level;
                lines += linesCleared;
                
                // 更新等级
                level = Math.floor(lines / 10) + 1;
                
                // 更新速度
                dropInterval = Math.max(100, 1000 - (level - 1) * 100);
                
                // 更新显示
                updateStats();
            }
        }
        
        // 更新统计信息
        function updateStats() {
            scoreElement.textContent = score;
            levelElement.textContent = level;
            linesElement.textContent = lines;
        }
        
        // 生成新的方块
        function newPiece() {
            currentPiece = nextPiece || createPiece();
            nextPiece = createPiece();
            drawNextPiece();
            
            // 检查游戏是否结束
            if (collision(currentPiece, board)) {
                gameOver = true;
                gameLoop = null;
                alert("游戏结束!最终得分:" + score);
            }
        }
        
        // 主游戏循环
        function update(time = 0) {
            if (gameOver || isPaused) return;
            
            const deltaTime = time - lastTime;
            lastTime = time;
            
            dropCounter += deltaTime;
            if (dropCounter > dropInterval) {
                dropPiece();
                dropCounter = 0;
            }
            
            drawBoard();
            requestAnimationFrame(update);
        }
        
        // 下降方块
        function dropPiece() {
            currentPiece.pos.y++;
            if (collision(currentPiece, board)) {
                currentPiece.pos.y--;
                mergePiece();
                clearLines();
                newPiece();
            }
        }
        
        // 瞬间下落
        function hardDrop() {
            while (!collision(currentPiece, board, {y: 1})) {
                currentPiece.pos.y++;
            }
            dropPiece();
        }
        
        // 左移
        function moveLeft() {
            currentPiece.pos.x--;
            if (collision(currentPiece, board)) {
                currentPiece.pos.x++;
            }
        }
        
        // 右移
        function moveRight() {
            currentPiece.pos.x++;
            if (collision(currentPiece, board)) {
                currentPiece.pos.x--;
            }
        }
        
        // 开始/暂停游戏
        function togglePause() {
            isPaused = !isPaused;
            if (!isPaused && !gameOver) {
                lastTime = performance.now();
                requestAnimationFrame(update);
            }
        }
        
        // 重置游戏
        function resetGame() {
            board = createBoard();
            score = 0;
            level = 1;
            lines = 0;
            gameOver = false;
            isPaused = false;
            dropInterval = 1000;
            
            updateStats();
            newPiece();
            drawBoard();
            
            if (gameLoop) {
                cancelAnimationFrame(gameLoop);
            }
            gameLoop = requestAnimationFrame(update);
        }
        
        // 键盘控制
        document.addEventListener('keydown', event => {
            if (gameOver || isPaused) return;
            
            switch (event.keyCode) {
                case 37: // 左箭头
                    moveLeft();
                    break;
                case 39: // 右箭头
                    moveRight();
                    break;
                case 40: // 下箭头
                    dropPiece();
                    break;
                case 38: // 上箭头
                    rotatePiece();
                    break;
                case 32: // 空格
                    hardDrop();
                    break;
            }
        });
        
        // 按钮事件
        startButton.addEventListener('click', togglePause);
        resetButton.addEventListener('click', resetGame);
        
        // 初始化游戏
        let gameLoop;
        function init() {
            board = createBoard();
            score = 0;
            level = 1;
            lines = 0;
            gameOver = false;
            isPaused = false;
            dropInterval = 1000;
            
            updateStats();
            newPiece();
            drawBoard();
            
            gameLoop = requestAnimationFrame(update);
        }
        
        // 启动游戏
        init();
    </script>
</body>
</html>

        
预览
控制台