🎮ArcadeLab

♻️ 国际垃圾分类知识竞赛

by SwiftPanther92
881 lines35.0 KB
▶ Play
这是为您扩充后的垃圾分类知识竞赛游戏HTML代码,包含25道覆盖多国标准的题目和详细解析,难度与知识性都得到了提升。

```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>♻️ 国际垃圾分类知识竞赛</title>
    <style>
        /* ===== 全局重置 & 字体 ===== */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', 'PingFang SC', Roboto, 'Helvetica Neue', sans-serif;
            background: linear-gradient(145deg, #0b2b1e 0%, #1a4a33 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 16px;
            margin: 0;
        }
        /* ===== 主容器 ===== */
        .game-container {
            max-width: 560px;
            width: 100%;
            background: rgba(255, 255, 255, 0.92);
            backdrop-filter: blur(4px);
            border-radius: 48px 48px 32px 32px;
            padding: 24px 20px 30px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.1);
            transition: all 0.2s;
        }
        /* ===== 顶部:标题 + 分数 ===== */
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 18px;
            padding-bottom: 12px;
            border-bottom: 2px dashed #c0d6cc;
        }
        .header h1 {
            font-size: 22px;
            font-weight: 700;
            color: #1d4d3a;
            letter-spacing: 1px;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        .header h1 span {
            font-size: 26px;
        }
        .score-box {
            background: #1d4d3a;
            color: #f5ffe0;
            padding: 8px 18px;
            border-radius: 40px;
            font-weight: 600;
            font-size: 20px;
            box-shadow: inset 0 -3px 0 #3b7a5e;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        .score-box small {
            font-size: 14px;
            font-weight: 400;
            opacity: 0.8;
        }
        /* ===== 进度/关卡信息 ===== */
        .progress-area {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: #eaf3ee;
            padding: 10px 16px;
            border-radius: 60px;
            margin-bottom: 20px;
            font-size: 14px;
            font-weight: 500;
            color: #1d4d3a;
        }
        .level-badge {
            background: #1d4d3a;
            color: white;
            padding: 4px 18px;
            border-radius: 40px;
            font-size: 14px;
        }
        .question-counter {
            background: white;
            padding: 4px 16px;
            border-radius: 40px;
            box-shadow: 0 2px 6px rgba(0,0,0,0.05);
        }
        /* ===== 题目卡片 ===== */
        .question-card {
            background: white;
            border-radius: 28px;
            padding: 24px 18px 18px;
            box-shadow: 0 8px 24px rgba(0, 30, 20, 0.12);
            margin-bottom: 20px;
            min-height: 180px;
            display: flex;
            flex-direction: column;
            transition: all 0.2s;
        }
        .question-text {
            font-size: 19px;
            font-weight: 600;
            color: #0e2f22;
            line-height: 1.5;
            margin-bottom: 16px;
            padding: 0 4px;
        }
        .question-text .q-icon {
            margin-right: 8px;
        }
        .question-country {
            font-size: 14px;
            font-weight: 500;
            color: #3b7a5e;
            background: #eaf3ee;
            display: inline-block;
            padding: 2px 14px;
            border-radius: 40px;
            margin-bottom: 12px;
            align-self: flex-start;
        }
        /* ===== 选项网格 ===== */
        .options-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 12px;
            margin-top: 4px;
        }
        .option-btn {
            background: #f5faf7;
            border: 2px solid #dce8e1;
            border-radius: 60px;
            padding: 14px 8px;
            font-size: 16px;
            font-weight: 600;
            color: #1d4d3a;
            cursor: pointer;
            transition: all 0.15s ease;
            box-shadow: 0 2px 4px rgba(0,0,0,0.02);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
            text-align: center;
            line-height: 1.3;
        }
        .option-btn:active { transform: scale(0.96); }
        .option-btn:hover:not(:disabled) {
            background: #e4f0ea;
            border-color: #5d9b7e;
            transform: translateY(-1px);
        }
        .option-btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }
        .option-btn.correct {
            background: #2b7a4b;
            border-color: #1e5f39;
            color: white;
            box-shadow: 0 4px 12px rgba(43, 122, 75, 0.35);
        }
        .option-btn.wrong {
            background: #c74a4a;
            border-color: #a13232;
            color: white;
            box-shadow: 0 4px 12px rgba(199, 74, 74, 0.30);
        }
        .option-btn.reveal-correct {
            background: #2b7a4b;
            border-color: #1e5f39;
            color: white;
            opacity: 0.85;
        }
        .option-btn .opt-label {
            font-weight: 400;
            opacity: 0.7;
            margin-right: 2px;
        }
        /* ===== 反馈横幅 ===== */
        .feedback {
            margin: 14px 0 10px;
            padding: 12px 16px;
            border-radius: 40px;
            font-weight: 600;
            font-size: 15px;
            text-align: left;
            min-height: 60px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            gap: 4px;
            transition: all 0.2s;
            background: #f0f5f2;
            color: #1d4d3a;
            line-height: 1.5;
        }
        .feedback .fb-title {
            font-weight: 700;
            font-size: 16px;
        }
        .feedback .fb-explain {
            font-weight: 400;
            font-size: 14px;
            opacity: 0.9;
        }
        .feedback.success {
            background: #d4efe0;
            color: #125a34;
        }
        .feedback.error {
            background: #fde8e8;
            color: #b13b3b;
        }
        /* ===== 底部按钮 ===== */
        .action-bar {
            display: flex;
            gap: 12px;
            margin-top: 8px;
        }
        .btn {
            flex: 1;
            padding: 15px 10px;
            border: none;
            border-radius: 60px;
            font-size: 17px;
            font-weight: 700;
            cursor: pointer;
            transition: all 0.15s;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
            background: #eaf3ee;
            color: #1d4d3a;
            box-shadow: 0 4px 0 #bccfc2;
        }
        .btn:active { transform: translateY(3px); box-shadow: 0 1px 0 #bccfc2; }
        .btn-primary {
            background: #1d4d3a;
            color: white;
            box-shadow: 0 4px 0 #0e2f22;
        }
        .btn-primary:active { box-shadow: 0 1px 0 #0e2f22; }
        .btn-primary:disabled {
            opacity: 0.5;
            transform: translateY(2px);
            box-shadow: 0 2px 0 #0e2f22;
            pointer-events: none;
        }
        .btn-success {
            background: #2b7a4b;
            color: white;
            box-shadow: 0 4px 0 #1a5a34;
        }
        .btn-success:active { box-shadow: 0 1px 0 #1a5a34; }
        /* ===== 结算弹窗 ===== */
        .modal-overlay {
            display: none;
            position: fixed;
            top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0, 20, 12, 0.7);
            backdrop-filter: blur(6px);
            justify-content: center;
            align-items: center;
            z-index: 999;
            padding: 24px;
        }
        .modal-overlay.active { display: flex; }
        .modal-box {
            background: white;
            max-width: 400px;
            width: 100%;
            border-radius: 48px;
            padding: 36px 28px 32px;
            text-align: center;
            box-shadow: 0 30px 80px rgba(0,0,0,0.5);
            animation: popIn 0.3s ease;
        }
        @keyframes popIn {
            0% { transform: scale(0.85); opacity: 0; }
            100% { transform: scale(1); opacity: 1; }
        }
        .modal-box .big-icon { font-size: 64px; margin-bottom: 6px; }
        .modal-box h2 { font-size: 28px; color: #1d4d3a; margin: 4px 0 8px; }
        .modal-box .sub {
            font-size: 18px;
            color: #3b6b55;
            margin-bottom: 6px;
        }
        .modal-box .final-score {
            font-size: 48px;
            font-weight: 800;
            color: #1d4d3a;
            background: #eaf3ee;
            display: inline-block;
            padding: 4px 32px;
            border-radius: 60px;
            margin: 12px 0 16px;
        }
        .modal-box .stats {
            display: flex;
            justify-content: center;
            gap: 28px;
            font-size: 16px;
            color: #2d5a45;
            margin: 12px 0 20px;
        }
        .modal-box .stats span { font-weight: 700; }
        .modal-box .btn { margin-top: 8px; }
        /* ===== 响应式微调 ===== */
        @media (max-width: 480px) {
            .game-container { padding: 16px 14px 22px; border-radius: 32px; }
            .header h1 { font-size: 18px; }
            .score-box { font-size: 17px; padding: 6px 14px; }
            .question-text { font-size: 17px; }
            .option-btn { font-size: 14px; padding: 12px 6px; }
            .modal-box { padding: 28px 18px 24px; }
            .modal-box .final-score { font-size: 38px; padding: 2px 24px; }
            .feedback { font-size: 14px; }
        }
        /* ===== 小工具 ===== */
        .hidden { display: none !important; }
        .mt-2 { margin-top: 8px; }
        .gap-1 { gap: 4px; }
    </style>
</head>
<body>

    <!-- ==================== 主游戏容器 ==================== -->
    <div class="game-container" id="app">
        <!-- 头部 -->
        <div class="header">
            <h1><span>♻️</span> 分类竞赛</h1>
            <div class="score-box">
                <small>🏆</small> <span id="scoreDisplay">0</span>
            </div>
        </div>

        <!-- 进度 -->
        <div class="progress-area">
            <span class="level-badge" id="levelBadge">🌱 初级</span>
            <span class="question-counter" id="questionCounter">1 / 25</span>
        </div>

        <!-- 题目卡片 -->
        <div class="question-card" id="questionCard">
            <div class="question-country" id="countryLabel">🌍 中国标准</div>
            <div class="question-text" id="questionText">
                <span class="q-icon">❓</span> 点击下方「开始答题」
            </div>
            <div class="options-grid" id="optionsContainer">
                <button class="option-btn" disabled>—</button>
                <button class="option-btn" disabled>—</button>
                <button class="option-btn" disabled>—</button>
                <button class="option-btn" disabled>—</button>
            </div>
            <!-- 反馈 -->
            <div class="feedback" id="feedbackArea">💡 准备好了吗?</div>
        </div>

        <!-- 操作按钮 -->
        <div class="action-bar">
            <button class="btn btn-success" id="nextBtn" disabled>▶ 下一题</button>
            <button class="btn btn-primary" id="restartBtn">⟳ 重新开始</button>
        </div>
    </div>

    <!-- ==================== 结算弹窗 ==================== -->
    <div class="modal-overlay" id="resultModal">
        <div class="modal-box">
            <div class="big-icon" id="resultEmoji">🏁</div>
            <h2 id="resultTitle">闯关完成!</h2>
            <div class="sub" id="resultSub">你的垃圾分类知识水平</div>
            <div class="final-score" id="resultScore">0</div>
            <div class="stats">
                <div>✅ 正确 <span id="statCorrect">0</span></div>
                <div>❌ 错误 <span id="statWrong">0</span></div>
            </div>
            <button class="btn btn-success" id="modalRestartBtn">🔄 再来一局</button>
        </div>
    </div>

    <script>
        // ================================================================
        //  1. 题库 (25 道题, 涵盖多国标准, 含详细解析)
        // ================================================================
        const QUESTIONS = [
            // 中国标准
            {
                country: '🇨🇳 中国标准',
                question: '废弃的节能灯(含汞)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '节能灯管含有汞、铅等有害物质,属于有害垃圾,需特殊安全处理。'
            },
            {
                country: '🇨🇳 中国标准',
                question: '大棒骨、贝壳属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '大棒骨和贝壳质地坚硬,不易腐烂,不属于厨余垃圾,应归为其他垃圾。'
            },
            {
                country: '🇨🇳 中国标准',
                question: '过期化妆品(如口红、粉底)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '过期化妆品含有化学制剂和重金属,属于有害垃圾,不能随意丢弃。'
            },
            {
                country: '🇨🇳 中国标准',
                question: '污损的纸张、用过的纸巾属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '污损纸张和用过的纸巾因无法回收利用,归为其他垃圾。'
            },
            {
                country: '🇨🇳 中国标准',
                question: '中药药渣、茶叶渣属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 2,
                explanation: '中药药渣和茶叶渣易腐烂,属于厨余垃圾,可用于堆肥。'
            },
            // 日本标准
            {
                country: '🇯🇵 日本标准',
                question: '干净的塑料瓶(PET)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '日本对塑料瓶回收严格,属于“资源物”(可回收物),需拆解清洗后投放。'
            },
            {
                country: '🇯🇵 日本标准',
                question: '陶瓷碎片、玻璃杯(非瓶)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '日本将陶瓷碎片归类为“不燃垃圾”,即其他垃圾,不能与可回收物混放。'
            },
            {
                country: '🇯🇵 日本标准',
                question: '一次性筷子、木质包装属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '日本将一次性筷子归为“可燃垃圾”,但在四分类中对应其他垃圾(因不可回收)。'
            },
            {
                country: '🇯🇵 日本标准',
                question: '废旧电池、荧光灯管属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '日本将电池和荧光灯管归类为“有害垃圾”或“危险垃圾”,需专门回收。'
            },
            // 德国标准
            {
                country: '🇩🇪 德国标准',
                question: '废纸箱、旧报纸属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '德国对纸类回收体系完善,废纸箱和报纸属于“废纸”可回收物。'
            },
            {
                country: '🇩🇪 德国标准',
                question: '废旧电池、油漆桶属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '德国将电池、油漆等列为“Sonderabfall”(特殊垃圾),即有害垃圾。'
            },
            {
                country: '🇩🇪 德国标准',
                question: '厨余垃圾(剩饭剩菜)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 2,
                explanation: '德国有专门的“生物垃圾”桶,厨余垃圾用于堆肥,属于厨余垃圾。'
            },
            {
                country: '🇩🇪 德国标准',
                question: '玻璃瓶(无色、有色)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '德国玻璃回收率极高,玻璃瓶属于可回收物,需按颜色分类投放。'
            },
            // 美国标准 (纽约/加州等)
            {
                country: '🇺🇸 美国标准',
                question: '塑料购物袋属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '美国多数地区将塑料袋归为可回收物,但需注意清洁干燥,部分超市可回收。'
            },
            {
                country: '🇺🇸 美国标准',
                question: '废弃的电子产品(如手机、充电器)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '电子产品含重金属和有害物质,美国EPA将其列为有害废弃物,需专门回收。'
            },
            {
                country: '🇺🇸 美国标准',
                question: '食品包装纸(被油污污染)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '被油污污染的纸制品无法回收,美国多数地区将其归为其他垃圾。'
            },
            // 瑞典标准
            {
                country: '🇸🇪 瑞典标准',
                question: '玻璃镜片、陶瓷杯属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '瑞典将玻璃镜片和陶瓷视为不可回收物,归为“其他垃圾”或“残留废物”。'
            },
            {
                country: '🇸🇪 瑞典标准',
                question: '废旧床垫、沙发垫属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '瑞典将大件家具归为“ bulky waste”,在四分类中通常算作其他垃圾。'
            },
            {
                country: '🇸🇪 瑞典标准',
                question: '废弃的食用油(家用)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 2,
                explanation: '瑞典提倡将废油收集作为生物燃料,但仍归类为“有机垃圾”(厨余垃圾)。'
            },
            // 混合国际(易混淆)
            {
                country: '🌍 国际通用',
                question: '用过的一次性纸杯(内壁覆膜)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '覆膜纸杯难以分离回收,多数国家将其归为其他垃圾(不可回收)。'
            },
            {
                country: '🌍 国际通用',
                question: '废弃的X光片、胶片属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: 'X光片含银等重金属,属于有害垃圾,需特殊处理。'
            },
            {
                country: '🌍 国际通用',
                question: '用过的猫砂、宠物粪便属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 3,
                explanation: '猫砂和宠物粪便通常归为其他垃圾,不能用于堆肥(可能含有病原体)。'
            },
            {
                country: '🌍 国际通用',
                question: '废旧衣物、纺织品属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '大多数国家将干净废旧衣物列为可回收物(或捐赠),但污损则归为其他。'
            },
            {
                country: '🇨🇳 中国标准',
                question: '过期药品(如感冒药、抗生素)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '过期药品属于有害垃圾,不可随意丢弃,需投放至专用回收点。'
            },
            {
                country: '🇩🇪 德国标准',
                question: '铝箔、锡纸(干净)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 0,
                explanation: '德国将干净的铝箔归为“轻质包装”可回收物,可回收利用。'
            },
            {
                country: '🇯🇵 日本标准',
                question: '喷雾罐(发胶、杀虫剂)属于哪类垃圾?',
                options: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
                answer: 1,
                explanation: '日本将喷雾罐(含有害气体或可燃气体)归类为“有害垃圾”或“危险垃圾”。'
            }
        ];

        // 分类名称映射(用于显示)
        const CATEGORY_NAMES = ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'];
        const CATEGORY_EMOJIS = ['♻️', '☣️', '🍂', '🗑️'];

        // ================================================================
        //  2. 游戏状态
        // ================================================================
        let state = {
            currentIndex: 0,
            score: 0,
            correctCount: 0,
            wrongCount: 0,
            totalQuestions: QUESTIONS.length,
            isAnswered: false,
            gameOver: false,
            userAnswers: new Array(QUESTIONS.length).fill(-1)
        };

        // ================================================================
        //  3. DOM 引用
        // ================================================================
        const $ = (id) => document.getElementById(id);
        const questionText = $('questionText');
        const countryLabel = $('countryLabel');
        const optionsContainer = $('optionsContainer');
        const feedbackArea = $('feedbackArea');
        const scoreDisplay = $('scoreDisplay');
        const levelBadge = $('levelBadge');
        const questionCounter = $('questionCounter');
        const nextBtn = $('nextBtn');
        const restartBtn = $('restartBtn');
        const modalRestartBtn = $('modalRestartBtn');
        const resultModal = $('resultModal');
        const resultEmoji = $('resultEmoji');
        const resultTitle = $('resultTitle');
        const resultSub = $('resultSub');
        const resultScore = $('resultScore');
        const statCorrect = $('statCorrect');
        const statWrong = $('statWrong');

        // ================================================================
        //  4. 核心函数
        // ================================================================

        function resetGame() {
            state.currentIndex = 0;
            state.score = 0;
            state.correctCount = 0;
            state.wrongCount = 0;
            state.isAnswered = false;
            state.gameOver = false;
            state.userAnswers.fill(-1);

            resultModal.classList.remove('active');

            const btns = optionsContainer.querySelectorAll('.option-btn');
            btns.forEach(btn => btn.disabled = false);

            feedbackArea.className = 'feedback';
            feedbackArea.innerHTML = '💡 新的一局,加油!';

            nextBtn.disabled = true;

            renderQuestion();
            updateScoreAndProgress();
        }

        function renderQuestion() {
            if (state.gameOver) return;

            const q = QUESTIONS[state.currentIndex];
            if (!q) {
                endGame();
                return;
            }

            // 显示国家/标准
            countryLabel.textContent = `🌍 ${q.country}`;

            // 题目文本
            questionText.innerHTML = `<span class="q-icon">📌</span> ${q.question}`;

            // 选项
            const btns = optionsContainer.querySelectorAll('.option-btn');
            btns.forEach((btn, idx) => {
                btn.className = 'option-btn';
                btn.disabled = false;
                const emoji = CATEGORY_EMOJIS[idx] || '▪️';
                btn.innerHTML = `${emoji} ${q.options[idx]}`;
            });

            // 恢复已答状态
            const prevAnswer = state.userAnswers[state.currentIndex];
            if (prevAnswer !== -1) {
                const qData = QUESTIONS[state.currentIndex];
                const btns2 = optionsContainer.querySelectorAll('.option-btn');
                btns2.forEach((btn, idx) => {
                    btn.disabled = true;
                    if (idx === qData.answer) {
                        btn.classList.add('correct');
                    } else if (idx === prevAnswer && prevAnswer !== qData.answer) {
                        btn.classList.add('wrong');
                    }
                });
                state.isAnswered = true;
                nextBtn.disabled = false;
                const isCorrect = (prevAnswer === qData.answer);
                feedbackArea.className = `feedback ${isCorrect ? 'success' : 'error'}`;
                const icon = isCorrect ? '✅' : '❌';
                const title = isCorrect ? '回答正确! +10分' : `正确答案是 “${CATEGORY_NAMES[qData.answer]}”`;
                feedbackArea.innerHTML = `<div class="fb-title">${icon} ${title}</div><div class="fb-explain">💡 ${qData.explanation}</div>`;
            } else {
                state.isAnswered = false;
                nextBtn.disabled = true;
                feedbackArea.className = 'feedback';
                feedbackArea.innerHTML = '🤔 选择一个选项吧';
                const btns3 = optionsContainer.querySelectorAll('.option-btn');
                btns3.forEach(btn => {
                    btn.className = 'option-btn';
                    btn.disabled = false;
                });
            }

            updateScoreAndProgress();
        }

        function handleOptionClick(index) {
            if (state.isAnswered || state.gameOver) return;
            if (state.userAnswers[state.currentIndex] !== -1) return;

            const q = QUESTIONS[state.currentIndex];
            const isCorrect = (index === q.answer);
            const btns = optionsContainer.querySelectorAll('.option-btn');

            btns.forEach(btn => btn.disabled = true);

            btns.forEach((btn, idx) => {
                if (idx === q.answer) {
                    btn.classList.add('correct');
                } else if (idx === index && !isCorrect) {
                    btn.classList.add('wrong');
                }
            });

            state.userAnswers[state.currentIndex] = index;
            state.isAnswered = true;

            if (isCorrect) {
                state.score += 10;
                state.correctCount += 1;
                feedbackArea.className = 'feedback success';
                feedbackArea.innerHTML = `<div class="fb-title">✅ 回答正确! +10分</div><div class="fb-explain">💡 ${q.explanation}</div>`;
            } else {
                state.wrongCount += 1;
                feedbackArea.className = 'feedback error';
                feedbackArea.innerHTML = `<div class="fb-title">❌ 正确答案是 “${CATEGORY_NAMES[q.answer]}”</div><div class="fb-explain">💡 ${q.explanation}</div>`;
            }

            updateScoreAndProgress();
            nextBtn.disabled = false;
        }

        function goToNextQuestion() {
            if (state.gameOver) return;
            if (!state.isAnswered) return;

            if (state.currentIndex + 1 < state.totalQuestions) {
                state.currentIndex++;
                renderQuestion();
            } else {
                endGame();
            }
        }

        function endGame() {
            state.gameOver = true;
            const btns = optionsContainer.querySelectorAll('.option-btn');
            btns.forEach(btn => btn.disabled = true);
            nextBtn.disabled = true;

            const total = state.totalQuestions;
            const correct = state.correctCount;
            const ratio = correct / total;

            let emoji, title, sub;
            if (ratio === 1) {
                emoji = '🌟';
                title = '完美通关!';
                sub = '你真是全球垃圾分类专家!';
            } else if (ratio >= 0.8) {
                emoji = '🏅';
                title = '优秀!';
                sub = '对各国分类标准非常了解!';
            } else if (ratio >= 0.6) {
                emoji = '📚';
                title = '还不错!';
                sub = '继续学习,你会更棒!';
            } else {
                emoji = '🌱';
                title = '需要加油!';
                sub = '多复习一下分类知识吧~';
            }

            resultEmoji.textContent = emoji;
            resultTitle.textContent = title;
            resultSub.textContent = sub;
            resultScore.textContent = state.score;
            statCorrect.textContent = state.correctCount;
            statWrong.textContent = state.wrongCount;

            resultModal.classList.add('active');
        }

        function updateScoreAndProgress() {
            scoreDisplay.textContent = state.score;
            const correct = state.correctCount;
            let level = '🌱 初级';
            if (correct >= 20) level = '🏆 大师';
            else if (correct >= 14) level = '🌿 进阶';
            else if (correct >= 7) level = '🌱 初级';
            levelBadge.textContent = level;
            const current = state.currentIndex + 1;
            questionCounter.textContent = `${Math.min(current, state.totalQuestions)} / ${state.totalQuestions}`;
        }

        function setupOptionListeners() {
            optionsContainer.addEventListener('click', (e) => {
                const btn = e.target.closest('.option-btn');
                if (!btn) return;
                const btns = optionsContainer.querySelectorAll('.option-btn');
                const index = Array.from(btns).indexOf(btn);
                if (index === -1) return;
                handleOptionClick(index);
            });
        }

        // ================================================================
        //  5. 初始化 & 事件绑定
        // ================================================================

        nextBtn.addEventListener('click', goToNextQuestion);

        function handleRestart() {
            resetGame();
        }
        restartBtn.addEventListener('click', handleRestart);
        modalRestartBtn.addEventListener('click', handleRestart);

        setupOptionListeners();

        // 键盘支持
        document.addEventListener('keydown', (e) => {
            if (e.key >= '1' && e.key <= '4') {
                const index = parseInt(e.key) - 1;
                const btns = optionsContainer.querySelectorAll('.option-btn');
                if (btns[index] && !btns[index].disabled) {
                    handleOptionClick(index);
                }
            }
            if (e.key === 'Enter' || e.key === ' ') {
                if (!nextBtn.disabled) {
                    e.preventDefault();
                    goToNextQuestion();
                }
            }
        });

        // 启动
        resetGame();
        console.log('♻️ 国际垃圾分类竞赛已启动! 题库:', QUESTIONS);
        console.log('💡 提示: 按键盘 1-4 快速选择,Enter 下一题');
    </script>

</body>
</html>
```

游戏机制与体验

游戏在原有答题框架上,扩充了题库并增加了知识深度,让您在挑战中学习。

· 多国标准题库:游戏内置了25道题目,覆盖中国、日本、德国、美国、瑞典等国家的垃圾分类标准。每道题都明确标注了所属国家或地区,帮助您对比不同体系的差异。
· 详细解析反馈:每道题无论答对或答错,都会在反馈区域显示详细的文字解析,说明该垃圾的分类依据和背后的环保逻辑,让学习贯穿始终。
· 难度与激励:题目涉及易混淆垃圾(如大棒骨、覆膜纸杯)和各国特殊规定(如日本的一次性筷子)。您仍然通过答题累积分数,完成全部题目后,会根据正确率获得从“需要加油”到“完美通关”的评级,并展示正确/错误统计。

---

优化建议: 您可以根据需要调整题库,在 QUESTIONS 数组中增删题目,或修改 explanation 字段中的解析内容,以适配更具体的教学场景。

Game Source: ♻️ 国际垃圾分类知识竞赛

Creator: SwiftPanther92

Libraries: none

Complexity: complex (881 lines, 35.0 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-swiftpanther92" to link back to the original. Then publish at arcadelab.ai/publish.