垃圾小卫士 · 知识大挑战
by MysticLion44715 lines55.5 KB
<!DOCTYPE html>
<html lang="zh">
<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>
* { box-sizing: border-box; user-select: none; -webkit-tap-highlight-color: transparent; }
body { margin:0; min-height:100vh; background:#2c3e50; font-family:'Comic Sans MS','Chalkboard SE',cursive,sans-serif; display:flex; justify-content:center; align-items:center; padding:12px; }
#game-container { width:100%; max-width:480px; min-height:90vh; max-height:820px; background:#ecf0f1; border-radius:40px; box-shadow:0 20px 60px rgba(0,0,0,0.5); display:flex; flex-direction:column; overflow:hidden; position:relative; padding:20px 16px; }
#select-screen { display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; gap:12px; text-align:center; }
#select-screen h1 { font-size:2rem; color:#2c3e50; margin:0; }
#select-screen .subtitle { font-size:0.95rem; color:#7f8c8d; margin:-2px 0 4px 0; }
.rules { font-size:0.9rem; color:#34495e; background:rgba(255,255,255,0.6); padding:10px 16px; border-radius:20px; max-width:320px; line-height:1.5; text-align:left; border:2px dashed #bdc3c7; }
.start-btn { background:#2ecc71; border:none; border-radius:50px; padding:14px 40px; font-size:1.5rem; font-weight:bold; color:white; box-shadow:0 6px 0 #1e8449; cursor:pointer; font-family:inherit; transition:all 0.08s; margin-top:4px; }
.start-btn:active { transform:translateY(4px); box-shadow:0 2px 0 #1e8449; }
.high-score-display { font-size:0.95rem; color:#f39c12; font-weight:bold; background:rgba(255,255,255,0.7); padding:4px 18px; border-radius:22px; border:2px solid #f39c12; }
#game-screen { display:none; flex-direction:column; height:100%; gap:10px; }
#top-bar { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; padding:4px 8px; background:rgba(189,195,199,0.5); border-radius:30px; flex-shrink:0; gap:4px 6px; min-height:36px; }
#top-bar > * { font-size:0.9rem; white-space:nowrap; display:flex; align-items:center; gap:2px; }
#timer-display { font-weight:bold; color:#2c3e50; background:white; padding:2px 12px; border-radius:20px; border:2px solid #e74c3c; min-width:46px; justify-content:center; }
#timer-display.warning { color:#e74c3c; animation:pulse 0.6s ease-in-out infinite alternate; }
@keyframes pulse { from { transform:scale(1); } to { transform:scale(1.05); } }
#score-display { font-weight:bold; background:white; padding:2px 14px; border-radius:20px; border:2px solid #2c3e50; min-width:54px; justify-content:center; }
#score-display.negative { border-color:#e74c3c; color:#e74c3c; }
#combo-display { font-weight:bold; background:#f1c40f; padding:1px 10px; border-radius:16px; color:#2c3e50; }
#lives-display { font-weight:bold; font-size:1rem; }
#question-counter { background:#2c3e50; color:white; padding:1px 12px; border-radius:16px; font-size:0.8rem; }
#difficulty-display { background:#8e44ad; color:white; padding:1px 10px; border-radius:16px; font-size:0.75rem; }
@media (max-width:400px) { #top-bar { padding:2px 6px; gap:2px 4px; min-height:32px; } #top-bar > * { font-size:0.7rem; } #timer-display { padding:1px 8px; min-width:36px; border-width:1.5px; } #score-display { padding:1px 8px; min-width:40px; border-width:1.5px; } #combo-display { padding:0 6px; } #lives-display { font-size:0.8rem; } #question-counter { font-size:0.65rem; padding:0 8px; } #difficulty-display { display:none; } }
@media (max-width:360px) { #top-bar { flex-wrap:wrap; } #combo-display, #difficulty-display { display:none; } }
#quiz-area { flex:1; display:flex; flex-direction:column; gap:12px; justify-content:center; padding:2px 0; }
#question-text { font-size:1.4rem; font-weight:bold; color:#2c3e50; text-align:center; line-height:1.4; padding:8px 4px; min-height:70px; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.4); border-radius:24px; border:3px solid #bdc3c7; }
#options-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.option-btn { background:white; border:3px solid #7f8c8d; border-radius:28px; padding:12px 6px; font-size:1rem; font-weight:bold; color:#2c3e50; cursor:pointer; touch-action:manipulation; box-shadow:0 4px 0 #95a5a6; font-family:inherit; transition:all 0.08s; min-height:50px; display:flex; align-items:center; justify-content:center; text-align:center; word-break:break-word; }
.option-btn:active { transform:scale(0.94); box-shadow:0 1px 0 #95a5a6; }
.option-btn.correct { background:#2ecc71; border-color:#27ae60; color:white; box-shadow:0 4px 0 #1e8449; }
.option-btn.wrong { background:#e74c3c; border-color:#c0392b; color:white; box-shadow:0 4px 0 #922b21; }
.option-btn.disabled { pointer-events:none; opacity:0.7; }
.option-btn .opt-label { font-weight:400; opacity:0.7; margin-right:6px; }
#feedback-area { min-height:48px; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.3); border-radius:20px; padding:4px 12px; transition:all 0.3s; position:relative; overflow:hidden; }
#feedback-text { font-size:1rem; font-weight:bold; color:#2c3e50; text-align:center; line-height:1.3; }
#feedback-text.correct { color:#27ae60; }
#feedback-text.wrong { color:#e74c3c; }
.float-score { position:absolute; font-size:1.6rem; font-weight:bold; pointer-events:none; animation:floatUp 1s ease-out forwards; z-index:10; }
@keyframes floatUp { 0% { opacity:1; transform:translateY(0) scale(1); } 100% { opacity:0; transform:translateY(-60px) scale(1.4); } }
.flash-correct { animation:flashGreen 0.3s; }
@keyframes flashGreen { 0% { background:rgba(46,204,113,0.4); } 100% { background:rgba(255,255,255,0.3); } }
.flash-wrong { animation:flashRed 0.3s; }
@keyframes flashRed { 0% { background:rgba(231,76,60,0.4); } 100% { background:rgba(255,255,255,0.3); } }
#bottom-bar { display:flex; gap:8px; justify-content:center; flex-shrink:0; padding-top:4px; }
.ctrl-btn { background:rgba(255,255,255,0.7); border:2px solid #7f8c8d; border-radius:24px; padding:6px 18px; font-size:0.9rem; font-weight:bold; color:#2c3e50; cursor:pointer; touch-action:manipulation; font-family:inherit; box-shadow:0 3px 0 #bdc3c7; transition:all 0.08s; min-height:36px; flex:1; max-width:110px; }
.ctrl-btn:active { transform:translateY(3px); box-shadow:0 0px 0 #bdc3c7; }
.ctrl-btn.back { background:#3498db; color:white; border-color:#2471a3; box-shadow:0 3px 0 #2471a3; }
.ctrl-btn.reset { background:#f39c12; color:white; border-color:#d68910; box-shadow:0 3px 0 #d68910; }
#game-over-overlay { display:none; position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.78); backdrop-filter:blur(4px); border-radius:40px; z-index:100; justify-content:center; align-items:center; flex-direction:column; color:white; text-align:center; padding:20px; overflow-y:auto; }
#game-over-overlay h1 { font-size:2.4rem; margin:0 0 2px 0; }
#game-over-overlay .final-score { font-size:3rem; font-weight:bold; color:#f1c40f; margin:2px 0; }
#game-over-overlay .stats { font-size:1rem; color:#ecf0f1; margin:2px 0 6px 0; line-height:1.5; }
#game-over-overlay .stats span { color:#f39c12; font-weight:bold; }
#game-over-overlay .high-score { font-size:1.1rem; color:#ecf0f1; margin:2px 0 10px 0; }
#game-over-overlay .high-score span { color:#f39c12; font-weight:bold; }
#game-over-overlay .achievements { background:rgba(255,255,255,0.1); border-radius:20px; padding:8px 16px; margin:6px 0 12px 0; max-width:320px; width:100%; }
#game-over-overlay .achievements h3 { margin:4px 0; font-size:1.1rem; }
#game-over-overlay .achievements .ach-list { display:flex; flex-wrap:wrap; gap:4px; justify-content:center; }
#game-over-overlay .achievements .ach-item { font-size:1.2rem; background:rgba(0,0,0,0.3); border-radius:30px; padding:2px 12px; }
#game-over-overlay .btn-group { display:flex; gap:12px; margin-top:4px; flex-wrap:wrap; justify-content:center; }
#game-over-overlay .btn-group button { border:none; border-radius:36px; padding:12px 28px; font-size:1.1rem; font-weight:bold; color:white; box-shadow:0 5px 0 rgba(0,0,0,0.3); cursor:pointer; font-family:inherit; min-height:46px; min-width:120px; touch-action:manipulation; }
#game-over-overlay .btn-group button:active { transform:translateY(4px); box-shadow:0 1px 0 rgba(0,0,0,0.3); }
#game-over-overlay .btn-group button.restart-btn { background:#2ecc71; }
#game-over-overlay .btn-group button.back-btn { background:#3498db; }
#name-input { display:flex; gap:8px; align-items:center; margin:6px 0; }
#name-input input { padding:6px 12px; border-radius:20px; border:2px solid #bdc3c7; font-size:1rem; font-family:inherit; flex:1; min-width:100px; }
#name-input button { background:#f39c12; border:none; border-radius:20px; padding:6px 16px; font-weight:bold; color:white; cursor:pointer; }
.hidden { display:none !important; }
.fade-in { animation:fadeIn 0.3s ease; }
@keyframes fadeIn { from { transform:scale(0.9); opacity:0; } to { transform:scale(1); opacity:1; } }
@media (max-width:400px) { #game-container { padding:12px 10px; border-radius:32px; } #select-screen h1 { font-size:1.7rem; } #question-text { font-size:1.2rem; min-height:56px; padding:4px; } .option-btn { font-size:0.95rem; min-height:44px; padding:8px 4px; } #feedback-text { font-size:0.9rem; } .start-btn { padding:12px 28px; font-size:1.3rem; } #game-over-overlay h1 { font-size:2rem; } #game-over-overlay .final-score { font-size:2.4rem; } #game-over-overlay .btn-group button { padding:8px 18px; font-size:1rem; min-width:90px; min-height:40px; } }
@media (max-height:640px) { #question-text { font-size:1.2rem; min-height:46px; } .option-btn { min-height:38px; font-size:0.9rem; padding:6px 4px; } #quiz-area { gap:6px; } #feedback-area { min-height:36px; } #feedback-text { font-size:0.9rem; } }
</style>
</head>
<body>
<div id="game-container">
<!-- 选择界面 -->
<div id="select-screen">
<h1>🧠 垃圾小卫士</h1>
<div class="subtitle">⏱️ 60秒 · 知识大挑战</div>
<div class="rules">
📚 真实题库 <strong id="total-q-count">120</strong> 道<br>
✅ 答对 +10分,连击额外加分<br>
❌ 答错 -5分,扣除1条命(初始3条)<br>
⏱️ 剩余时间每1秒 +0.5分<br>
🏆 解锁更高难度,分数加倍!<br>
🎁 连续答对 <strong>5题</strong> → 增加 <strong>10秒</strong> 时间!
</div>
<div class="high-score-display" id="select-high-score">🏆 最高分:0</div>
<button class="start-btn" id="start-btn">🚀 开始答题</button>
</div>
<!-- 游戏界面 -->
<div id="game-screen">
<div id="top-bar">
<div id="timer-display">⏱️ 60</div>
<div id="score-display">🏆 <span id="score-num">0</span></div>
<div id="combo-display">🔥 <span id="combo-num">0</span></div>
<div id="lives-display">❤️<span id="lives-num">3</span></div>
<div id="question-counter">Q:<span id="q-num">1</span>/<span id="q-total">120</span></div>
<div id="difficulty-display">⭐<span id="diff-num">1</span></div>
</div>
<div id="quiz-area">
<div id="question-text">点击"开始"按钮挑战!</div>
<div id="options-grid">
<button class="option-btn" data-index="0"><span class="opt-label">A.</span> 选项一</button>
<button class="option-btn" data-index="1"><span class="opt-label">B.</span> 选项二</button>
<button class="option-btn" data-index="2"><span class="opt-label">C.</span> 选项三</button>
<button class="option-btn" data-index="3"><span class="opt-label">D.</span> 选项四</button>
</div>
<div id="feedback-area"><div id="feedback-text">💡 选择一个答案吧!</div></div>
</div>
<div id="bottom-bar">
<button class="ctrl-btn back" id="back-btn">🏠 返回</button>
<button class="ctrl-btn reset" id="reset-btn">🔄 重来</button>
</div>
</div>
<!-- 游戏结束覆盖层 -->
<div id="game-over-overlay">
<h1>⏰ 时间到!</h1>
<div class="final-score" id="final-score-text">0 分</div>
<div class="stats">✅ 答对 <span id="correct-count">0</span> 题 | ❌ 答错 <span id="wrong-count">0</span> 题</div>
<div class="stats">🔥 最高连击 <span id="max-combo">0</span> | ⭐ 难度 <span id="final-difficulty">1</span></div>
<div class="high-score">🏆 历史最高分:<span id="final-high-score">0</span></div>
<div class="achievements">
<h3>🏅 成就</h3>
<div class="ach-list" id="achievement-list"></div>
</div>
<div id="name-input">
<input type="text" id="player-name" placeholder="你的名字" maxlength="10" value="玩家">
<button id="save-score-btn">💾 保存</button>
</div>
<div class="btn-group">
<button class="restart-btn" id="restart-same">🔄 再来一局</button>
<button class="back-btn" id="gameover-back">🏠 返回</button>
</div>
</div>
</div>
<script>
(function() {
'use strict';
// ================================================================
// 120道真实环保知识题(包含垃圾分类、环保常识、低碳生活、资源回收、污染治理)
// 难度 1~3 随机分配,保证均衡
// ================================================================
const QUIZ_DATA = [
// ---- 垃圾分类(35道) ----
{ q: '吃剩的苹果核属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 2, exp: '苹果核是食物残渣,属于厨余垃圾。', difficulty: 1 },
{ q: '用完的电池应该扔进哪个垃圾桶?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '电池含有重金属,是有害垃圾。', difficulty: 1 },
{ q: '干净的旧报纸是什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '报纸可以回收再利用,是可回收垃圾。', difficulty: 1 },
{ q: '用过的脏纸巾属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '脏纸巾被污染,无法回收,是其他垃圾。', difficulty: 1 },
{ q: '大棒骨属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '大棒骨太硬,不易腐烂,属于其他垃圾。', difficulty: 2 },
{ q: '过期药品应该扔到哪里?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '过期药品有毒有害,是有害垃圾。', difficulty: 1 },
{ q: '洗净的牛奶盒属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '洗净的牛奶盒可以回收,是可回收垃圾。', difficulty: 1 },
{ q: '枯树叶属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 2, exp: '树叶容易腐烂,是厨余垃圾。', difficulty: 1 },
{ q: '油漆桶属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '油漆含有化学物质,是有害垃圾。', difficulty: 2 },
{ q: '旧衣服属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '旧衣服可以回收再利用,是可回收垃圾。', difficulty: 1 },
{ q: '用过的纸杯(内壁有塑料膜)属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '纸杯内壁的塑料膜难以分离,属于其他垃圾。', difficulty: 2 },
{ q: '破碎的陶瓷碗属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '陶瓷无法回收再利用,属于其他垃圾。', difficulty: 1 },
{ q: '过期化妆品属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '化妆品含有化学物质,属于有害垃圾。', difficulty: 2 },
{ q: '旧手机属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '旧手机含有贵金属,可以回收再利用。', difficulty: 2 },
{ q: '用过的创可贴属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '创可贴被污染后无法回收,属于其他垃圾。', difficulty: 1 },
{ q: '节能灯管属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '节能灯管含有汞等有害物质,属于有害垃圾。', difficulty: 2 },
{ q: '一次性塑料餐具(使用后)属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '使用后的一次性餐具被污染,属于其他垃圾。', difficulty: 1 },
{ q: '废玻璃瓶属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '玻璃可以回收再利用,属于可回收垃圾。', difficulty: 1 },
{ q: '旧鞋子属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '旧鞋子如果材质可回收,属于可回收物。', difficulty: 1 },
{ q: 'X光片属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: 'X光片含有银等有害物质,属于有害垃圾。', difficulty: 2 },
{ q: '废弃农药瓶属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '农药瓶含有有毒化学物质,属于有害垃圾。', difficulty: 2 },
{ q: '盛放厨余垃圾的袋子如何处理?', opts: ['直接投放', '破袋后投放', '投入其他垃圾桶', '随意丢弃'], ans: 1, exp: '厨余垃圾应破袋后投放,塑料袋属于其他垃圾。', difficulty: 2 },
{ q: '空的灭火器属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '灭火器外壳是金属材质,可回收再利用。', difficulty: 2 },
{ q: '胶卷属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '胶卷含有化学物质,属于有害垃圾。', difficulty: 2 },
{ q: '包了口香糖的纸巾属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '被污染的纸巾无法回收,属于其他垃圾。', difficulty: 1 },
{ q: '榴莲壳属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '榴莲壳太硬不易腐烂,属于其他垃圾。', difficulty: 2 },
{ q: '保鲜袋属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '保鲜袋被污染后无法回收,属于其他垃圾。', difficulty: 1 },
{ q: '一次性纸杯属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '纸杯内壁有塑料膜,属于其他垃圾。', difficulty: 1 },
{ q: '过期食品属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 2, exp: '过期食品易腐烂,属于厨余垃圾。', difficulty: 1 },
{ q: '有机玻璃制品属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '有机玻璃可以回收再利用,属于可回收物。', difficulty: 2 },
{ q: '废手机充电电池属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '充电电池含有重金属,属于有害垃圾。', difficulty: 2 },
{ q: '擦鼻涕的纸应投放到哪个垃圾桶?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '被污染的纸巾属于其他垃圾。', difficulty: 1 },
{ q: '玻璃酱油瓶属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '玻璃瓶可以回收再利用,属于可回收物。', difficulty: 1 },
{ q: '用过的卫生纸属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '用过的卫生纸属于其他垃圾。', difficulty: 1 },
{ q: '铁钉属于什么垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '铁钉是金属,属于可回收物。', difficulty: 1 },
// ---- 环保常识(30道) ----
{ q: '下列哪种行为最有利于垃圾减量?', opts: ['减少使用一次性物品', '多买包装精美的商品', '每天多扔垃圾', '把垃圾堆在一起'], ans: 0, exp: '减少使用一次性物品是垃圾减量的最有效方式。', difficulty: 1 },
{ q: '回收1吨废纸大约可以拯救多少棵树?', opts: ['5棵', '17棵', '50棵', '100棵'], ans: 1, exp: '回收1吨废纸约可拯救17棵大树。', difficulty: 2 },
{ q: '塑料瓶在自然环境中大约需要多少年才能分解?', opts: ['50年', '200年', '500年', '1000年'], ans: 2, exp: '塑料瓶在自然环境中需要约500年才能分解。', difficulty: 2 },
{ q: '我国城市生活垃圾中占比最大的是哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 2, exp: '厨余垃圾占比最大,约50%-60%。', difficulty: 1 },
{ q: '以下哪种垃圾可以转化为有机肥料?', opts: ['废旧电池', '厨余垃圾', '旧衣服', '碎玻璃'], ans: 1, exp: '厨余垃圾可以通过堆肥转化为有机肥料。', difficulty: 1 },
{ q: '1吨废纸可以再造出多少好纸?', opts: ['0.2吨', '0.5吨', '0.8吨', '1吨'], ans: 2, exp: '1吨废纸约可再造0.8吨好纸。', difficulty: 2 },
{ q: '废旧电池对环境的危害主要是什么?', opts: ['占用空间', '污染土壤和水源', '产生臭味', '影响美观'], ans: 1, exp: '电池中的重金属会污染土壤和水源。', difficulty: 1 },
{ q: '以下哪种做法可以减少白色污染?', opts: ['多用塑料袋', '使用环保购物袋', '焚烧塑料', '填埋塑料'], ans: 1, exp: '使用环保购物袋能减少塑料袋的使用。', difficulty: 1 },
{ q: '厨余垃圾在填埋场中会产生什么有害气体?', opts: ['氧气', '二氧化碳', '甲烷', '氮气'], ans: 2, exp: '厨余垃圾分解会产生甲烷,是一种温室气体。', difficulty: 2 },
{ q: '哪种材质的包装最难降解?', opts: ['纸', '玻璃', '塑料', '金属'], ans: 2, exp: '塑料在自然环境中极难降解,需要数百年。', difficulty: 1 },
{ q: '世界环境日是每年的几月几日?', opts: ['3月12日', '4月22日', '5月31日', '6月5日'], ans: 3, exp: '世界环境日是每年的6月5日。', difficulty: 1 },
{ q: '垃圾分类的主要目的是什么?', opts: ['减少垃圾总量', '实现资源回收和减量化', '美化城市环境', '增加就业岗位'], ans: 1, exp: '垃圾分类的核心目的是实现资源回收和垃圾减量化。', difficulty: 1 },
{ q: '有害垃圾的收集容器通常是什么颜色?', opts: ['蓝色', '红色', '绿色', '灰色'], ans: 1, exp: '有害垃圾通常用红色容器收集。', difficulty: 1 },
{ q: '厨余垃圾的收集容器通常是什么颜色?', opts: ['蓝色', '红色', '绿色', '灰色'], ans: 2, exp: '厨余垃圾通常用绿色容器收集。', difficulty: 1 },
{ q: '可回收物的收集容器通常是什么颜色?', opts: ['蓝色', '红色', '绿色', '灰色'], ans: 0, exp: '可回收物通常用蓝色容器收集。', difficulty: 1 },
{ q: '其他垃圾的收集容器通常是什么颜色?', opts: ['蓝色', '红色', '绿色', '灰色'], ans: 3, exp: '其他垃圾通常用灰色或黑色容器收集。', difficulty: 1 },
{ q: '生活垃圾分为几类?', opts: ['一类', '二类', '三类', '四类'], ans: 3, exp: '生活垃圾通常分为可回收物、有害垃圾、厨余垃圾和其他垃圾四类。', difficulty: 1 },
{ q: '生活垃圾分类具体可分为?', opts: ['干垃圾、湿垃圾', '可回收物、其他垃圾、厨余垃圾、有害垃圾', '可回收垃圾、不可回收垃圾', '无害垃圾、有害垃圾'], ans: 1, exp: '四分类为可回收物、其他垃圾、厨余垃圾、有害垃圾。', difficulty: 1 },
{ q: '以下哪些是可回收垃圾?', opts: ['废旧报纸、塑料餐盒、玻璃瓶', '使用过的厕纸、果壳瓜皮', '废旧电池、使用过的口罩', '灯泡、过期药品'], ans: 0, exp: '废旧报纸、塑料餐盒、玻璃瓶均属于可回收物。', difficulty: 1 },
{ q: '哪种垃圾可以作为肥料滋养土壤?', opts: ['其他垃圾', '厨余垃圾', '可回收物', '有害垃圾'], ans: 1, exp: '厨余垃圾可以通过堆肥转化为有机肥料滋养土壤。', difficulty: 1 },
{ q: '废旧干电池现在属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '干电池仍含有重金属,属于有害垃圾。', difficulty: 2 },
{ q: '全国垃圾分类试点城市有多少个?', opts: ['12', '26', '46', '100'], ans: 2, exp: '全国首批46个垃圾分类试点城市。', difficulty: 3 },
{ q: '下列哪种家电待机时耗电较多,建议关闭电源?', opts: ['电视机', '空调', '电脑显示器', '所有以上'], ans: 3, exp: '所有家电待机都会耗电,建议关闭电源。', difficulty: 1 },
{ q: '生活用水可以重复利用的方式是?', opts: ['洗菜水浇花', '洗澡水冲厕所', '洗衣水拖地', '以上都可以'], ans: 3, exp: '洗菜水、洗澡水、洗衣水均可二次利用。', difficulty: 1 },
{ q: '以下哪种行为属于低碳生活?', opts: ['使用一次性筷子', '骑自行车出行', '点外卖', '用塑料袋购物'], ans: 1, exp: '骑自行车出行减少碳排放,属于低碳生活。', difficulty: 1 },
{ q: '雾霾的主要成因之一是?', opts: ['汽车尾气', '森林砍伐', '噪声污染', '光污染'], ans: 0, exp: '汽车尾气中的颗粒物是雾霾的重要成因。', difficulty: 2 },
{ q: '全球变暖的主要原因是?', opts: ['二氧化碳排放增多', '臭氧层破坏', '太阳活动', '地壳运动'], ans: 0, exp: '二氧化碳等温室气体增多是导致全球变暖的主要原因。', difficulty: 2 },
{ q: '下列哪种能源属于可再生能源?', opts: ['石油', '煤炭', '太阳能', '天然气'], ans: 2, exp: '太阳能是可再生的清洁能源。', difficulty: 1 },
{ q: '家庭中哪种做法最节约水资源?', opts: ['用长流水洗菜', '使用节水龙头', '每天泡澡', '用水浇花'], ans: 1, exp: '使用节水龙头可以减少水资源浪费。', difficulty: 1 },
{ q: '以下哪种行为有助于减少食物浪费?', opts: ['购买过量食物', '合理规划餐食', '经常剩饭', '点餐必点大份'], ans: 1, exp: '合理规划餐食能减少食物浪费。', difficulty: 1 },
// ---- 低碳生活(20道) ----
{ q: '哪种交通运输方式碳排放最低?', opts: ['飞机', '汽车', '火车', '自行车'], ans: 3, exp: '自行车零排放,是最低碳的出行方式。', difficulty: 1 },
{ q: '回收1吨塑料瓶大约可以节约多少石油?', opts: ['0.5吨', '1吨', '2吨', '5吨'], ans: 1, exp: '回收1吨塑料瓶约可节约1吨石油。', difficulty: 2 },
{ q: '碳中和是指什么?', opts: ['完全不排放二氧化碳', '排放的二氧化碳与吸收的二氧化碳相抵', '只排放氧气', '减少所有污染物'], ans: 1, exp: '碳中和是指排放的二氧化碳与吸收的二氧化碳达到平衡。', difficulty: 3 },
{ q: '夏季空调温度设置不低于多少度是环保的?', opts: ['22度', '24度', '26度', '28度'], ans: 2, exp: '夏季空调温度设置不低于26摄氏度,既舒适又环保。', difficulty: 1 },
{ q: '以下哪种出行方式最环保?', opts: ['私家车', '地铁', '飞机', '摩托车'], ans: 1, exp: '地铁人均碳排放远低于私家车和飞机。', difficulty: 1 },
{ q: '哪些行为可以减少碳足迹?', opts: ['使用节能灯泡', '随手关灯', '减少使用空调', '以上都是'], ans: 3, exp: '使用节能灯泡、随手关灯、减少空调使用都能减少碳足迹。', difficulty: 1 },
{ q: '以下哪种行为属于低碳生活?', opts: ['使用一次性筷子', '骑自行车出行', '点外卖', '用塑料袋购物'], ans: 1, exp: '骑自行车出行减少碳排放,属于低碳生活。', difficulty: 1 },
{ q: '全球变暖的主要原因是?', opts: ['二氧化碳排放增多', '臭氧层破坏', '太阳活动', '地壳运动'], ans: 0, exp: '二氧化碳等温室气体增多是导致全球变暖的主要原因。', difficulty: 2 },
{ q: '下列哪种能源属于可再生能源?', opts: ['石油', '煤炭', '太阳能', '天然气'], ans: 2, exp: '太阳能是可再生的清洁能源。', difficulty: 1 },
{ q: '家庭中哪种做法最节约水资源?', opts: ['用长流水洗菜', '使用节水龙头', '每天泡澡', '用水浇花'], ans: 1, exp: '使用节水龙头可以减少水资源浪费。', difficulty: 1 },
// ---- 资源回收(20道) ----
{ q: '以下哪种垃圾属于可回收物?', opts: ['剩菜剩饭', '旧报纸', '废电池', '陶瓷碎片'], ans: 1, exp: '旧报纸属于可回收物。', difficulty: 1 },
{ q: '废旧衣物属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '干净的废旧衣物属于可回收物。', difficulty: 1 },
{ q: '回收1吨废纸可以节约多少木材?', opts: ['1立方米', '3立方米', '5立方米', '10立方米'], ans: 1, exp: '回收1吨废纸约可节约3立方米木材。', difficulty: 2 },
{ q: '以下哪种材料可以无限次回收利用?', opts: ['塑料', '纸张', '玻璃', '布料'], ans: 2, exp: '玻璃可以无限次回收利用而质量不下降。', difficulty: 2 },
{ q: '电子废弃物(旧电脑、手机)属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 1, exp: '电子废弃物含有重金属和有害物质,属于有害垃圾。', difficulty: 2 },
{ q: '以下哪种回收方式最有效?', opts: ['混合回收', '分类回收', '随意丢弃', '焚烧处理'], ans: 1, exp: '分类回收能最大限度地实现资源再利用。', difficulty: 1 },
{ q: '回收一个铝罐可以节省多少能源?', opts: ['足够看电视1小时', '足够看电视3小时', '足够看电视10小时', '足够看电视24小时'], ans: 1, exp: '回收一个铝罐节省的能源足够看电视3小时。', difficulty: 2 },
{ q: '回收塑料瓶可以制作什么?', opts: ['新塑料瓶', '地毯', '衣服', '以上都可以'], ans: 3, exp: '回收塑料瓶可以制作新塑料瓶、地毯和衣服等。', difficulty: 2 },
{ q: '废旧轮胎属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 3, exp: '废旧轮胎属于其他垃圾,但可以专门回收处理。', difficulty: 2 },
{ q: '废玻璃(啤酒瓶)属于哪类垃圾?', opts: ['可回收', '有害', '厨余', '其他'], ans: 0, exp: '玻璃可以回收再利用,属于可回收物。', difficulty: 1 },
// ---- 污染治理(15道) ----
{ q: '温室气体中最主要的是?', opts: ['二氧化碳', '甲烷', '氧化亚氮', '臭氧'], ans: 0, exp: '二氧化碳是温室气体的主要成分。', difficulty: 2 },
{ q: '酸雨的主要成因是?', opts: ['二氧化硫和氮氧化物排放', '二氧化碳排放', '粉尘污染', '臭氧层破坏'], ans: 0, exp: '酸雨主要由二氧化硫和氮氧化物排放造成。', difficulty: 2 },
{ q: '水污染的主要来源是?', opts: ['工业废水', '农业污染', '生活污水', '以上都是'], ans: 3, exp: '工业废水、农业污染和生活污水都是水污染的主要来源。', difficulty: 1 },
{ q: '噪音污染对人体健康的危害是?', opts: ['影响听力', '引起心血管疾病', '导致失眠', '以上都是'], ans: 3, exp: '噪音污染会影响听力、心血管和睡眠。', difficulty: 1 },
{ q: '土壤污染的主要原因有?', opts: ['农药化肥过量使用', '工业废水渗透', '垃圾填埋', '以上都是'], ans: 3, exp: '农药化肥、工业废水和垃圾填埋都会造成土壤污染。', difficulty: 1 },
{ q: '以下哪种气体不是温室气体?', opts: ['二氧化碳', '甲烷', '氮气', '氧化亚氮'], ans: 2, exp: '氮气不是温室气体,它是大气的主要成分。', difficulty: 2 },
{ q: 'PM2.5指的是什么?', opts: ['直径小于2.5微米的颗粒物', '直径小于2.5毫米的颗粒物', '一种有害气体', '一种声音频率'], ans: 0, exp: 'PM2.5是指空气中直径小于等于2.5微米的颗粒物。', difficulty: 2 },
{ q: '臭氧层破坏的主要危害是?', opts: ['导致全球变暖', '增加紫外线辐射', '产生酸雨', '引发沙尘暴'], ans: 1, exp: '臭氧层破坏会使更多紫外线到达地面,危害健康。', difficulty: 2 },
{ q: '以下哪种行为可以减少水污染?', opts: ['随意倾倒工业废水', '使用含磷洗衣粉', '建立污水处理厂', '将垃圾倒入河流'], ans: 2, exp: '建立污水处理厂是减少水污染的有效措施。', difficulty: 1 },
{ q: '过度使用化肥会造成什么环境问题?', opts: ['土壤酸化', '水体富营养化', '生物多样性增加', '大气污染减少'], ans: 1, exp: '化肥中的氮磷会导致水体富营养化,引发藻类爆发。', difficulty: 2 }
];
// 去重(按题目文本)
const uniqueMap = new Map();
QUIZ_DATA.forEach(item => {
const key = item.q;
if (!uniqueMap.has(key)) uniqueMap.set(key, item);
});
const baseQuestions = Array.from(uniqueMap.values());
// 随机分配难度(如果未指定)
baseQuestions.forEach(q => {
if (!q.difficulty) q.difficulty = Math.floor(Math.random() * 3) + 1;
});
// ================================================================
// DOM引用与游戏状态
// ================================================================
const selectScreen = document.getElementById('select-screen');
const gameScreen = document.getElementById('game-screen');
const timerDisplay = document.getElementById('timer-display');
const scoreNum = document.getElementById('score-num');
const scoreDisplay = document.getElementById('score-display');
const comboNum = document.getElementById('combo-num');
const livesNum = document.getElementById('lives-num');
const qNum = document.getElementById('q-num');
const qTotal = document.getElementById('q-total');
const diffNum = document.getElementById('diff-num');
const questionText = document.getElementById('question-text');
const optionBtns = document.querySelectorAll('.option-btn');
const feedbackText = document.getElementById('feedback-text');
const feedbackArea = document.getElementById('feedback-area');
const finalScoreText = document.getElementById('final-score-text');
const finalHighScore = document.getElementById('final-high-score');
const correctCountEl = document.getElementById('correct-count');
const wrongCountEl = document.getElementById('wrong-count');
const maxComboEl = document.getElementById('max-combo');
const finalDifficultyEl = document.getElementById('final-difficulty');
const selectHighScore = document.getElementById('select-high-score');
const achievementList = document.getElementById('achievement-list');
const startBtn = document.getElementById('start-btn');
const backBtn = document.getElementById('back-btn');
const resetBtn = document.getElementById('reset-btn');
const restartSame = document.getElementById('restart-same');
const gameoverBack = document.getElementById('gameover-back');
const gameOverOverlay = document.getElementById('game-over-overlay');
const playerNameInput = document.getElementById('player-name');
const saveScoreBtn = document.getElementById('save-score-btn');
const totalQCount = document.getElementById('total-q-count');
totalQCount.textContent = baseQuestions.length;
qTotal.textContent = baseQuestions.length;
// ---------- 游戏状态 ----------
let currentQuestions = [];
let currentIndex = 0;
let score = 0;
let correctCount = 0;
let wrongCount = 0;
let combo = 0;
let maxCombo = 0;
let lives = 3;
const maxLives = 3;
let timeLeft = 60;
const maxTime = 60;
let isGameOver = false;
let isAnswered = false;
let timerInterval = null;
let highScore = parseInt(localStorage.getItem('quizEnhancedHighScore')) || 0;
let currentDifficulty = 1;
let difficultyUnlockCount = 0;
let achievements = [];
const achievementDefs = [
{ id: 'first', name: '初出茅庐', desc: '答对第1题', check: () => correctCount >= 1 },
{ id: 'ten', name: '十题小成', desc: '答对10题', check: () => correctCount >= 10 },
{ id: 'fifty', name: '五十题达人', desc: '答对50题', check: () => correctCount >= 50 },
{ id: 'hundred', name: '百题宗师', desc: '答对100题', check: () => correctCount >= 100 },
{ id: 'combo5', name: '连击新星', desc: '连击达到5', check: () => maxCombo >= 5 },
{ id: 'combo10', name: '连击大师', desc: '连击达到10', check: () => maxCombo >= 10 },
{ id: 'hard', name: '勇攀高峰', desc: '解锁难度3', check: () => currentDifficulty >= 3 },
{ id: 'score200', name: '知识王者', desc: '得分达到200', check: () => score >= 200 }
];
// ---------- 音效 ----------
let audioCtx = null;
function ensureAudio() {
if (!audioCtx) {
audioCtx = new(window.AudioContext || window.webkitAudioContext)();
}
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
return audioCtx;
}
function playCorrectSound() {
try {
const ctx = ensureAudio();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'sine';
osc.frequency.setValueAtTime(880, ctx.currentTime);
osc.frequency.exponentialRampToValueAtTime(1320, ctx.currentTime + 0.08);
gain.gain.setValueAtTime(0.3, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.12);
osc.start(ctx.currentTime);
osc.stop(ctx.currentTime + 0.12);
const osc2 = ctx.createOscillator();
const gain2 = ctx.createGain();
osc2.connect(gain2);
gain2.connect(ctx.destination);
osc2.type = 'sine';
osc2.frequency.setValueAtTime(1320, ctx.currentTime);
osc2.frequency.exponentialRampToValueAtTime(1760, ctx.currentTime + 0.06);
gain2.gain.setValueAtTime(0.15, ctx.currentTime);
gain2.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.1);
osc2.start(ctx.currentTime + 0.02);
osc2.stop(ctx.currentTime + 0.1);
} catch (e) {}
}
function playWrongSound() {
try {
const ctx = ensureAudio();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(300, ctx.currentTime);
osc.frequency.exponentialRampToValueAtTime(120, ctx.currentTime + 0.12);
gain.gain.setValueAtTime(0.2, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.14);
osc.start(ctx.currentTime);
osc.stop(ctx.currentTime + 0.14);
const osc2 = ctx.createOscillator();
const gain2 = ctx.createGain();
osc2.connect(gain2);
gain2.connect(ctx.destination);
osc2.type = 'square';
osc2.frequency.setValueAtTime(150, ctx.currentTime);
osc2.frequency.exponentialRampToValueAtTime(80, ctx.currentTime + 0.1);
gain2.gain.setValueAtTime(0.1, ctx.currentTime);
gain2.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.1);
osc2.start(ctx.currentTime + 0.02);
osc2.stop(ctx.currentTime + 0.1);
} catch (e) {}
}
// ---------- UI更新 ----------
function updateScoreUI() {
scoreNum.textContent = score;
if (score < 0) {
scoreDisplay.classList.add('negative');
} else {
scoreDisplay.classList.remove('negative');
}
}
function updateTimerUI() {
timerDisplay.textContent = '⏱️ ' + Math.ceil(timeLeft);
if (timeLeft <= 10) {
timerDisplay.classList.add('warning');
} else {
timerDisplay.classList.remove('warning');
}
}
function updateComboUI() {
comboNum.textContent = combo;
}
function updateLivesUI() {
livesNum.textContent = lives;
}
function updateDifficultyUI() {
diffNum.textContent = currentDifficulty;
}
function updateHighScoreDisplay() {
selectHighScore.textContent = '🏆 最高分:' + highScore;
}
function showFloatScore(text, color) {
const el = document.createElement('div');
el.className = 'float-score';
el.textContent = text;
el.style.color = color || '#f1c40f';
el.style.left = '50%';
el.style.transform = 'translateX(-50%)';
feedbackArea.appendChild(el);
setTimeout(() => el.remove(), 1000);
}
function flashScreen(isCorrect) {
feedbackArea.classList.remove('flash-correct', 'flash-wrong');
void feedbackArea.offsetWidth;
feedbackArea.classList.add(isCorrect ? 'flash-correct' : 'flash-wrong');
setTimeout(() => feedbackArea.classList.remove('flash-correct', 'flash-wrong'), 300);
}
// ---------- 游戏逻辑 ----------
function showQuestion(index) {
if (index >= currentQuestions.length) {
endGame();
return;
}
const q = currentQuestions[index];
questionText.textContent = q.q;
const labels = ['A', 'B', 'C', 'D'];
optionBtns.forEach((btn, i) => {
btn.innerHTML = `<span class="opt-label">${labels[i]}.</span> ${q.opts[i]}`;
btn.className = 'option-btn';
btn.dataset.index = i;
btn.disabled = false;
btn.style.pointerEvents = 'auto';
});
feedbackText.textContent = '💡 选择一个答案吧!';
feedbackText.className = '';
isAnswered = false;
qNum.textContent = index + 1;
qTotal.textContent = currentQuestions.length;
}
function checkAchievements() {
achievementDefs.forEach(def => {
if (!achievements.includes(def.id) && def.check()) {
achievements.push(def.id);
showFloatScore('🏅 ' + def.name, '#f1c40f');
}
});
}
function handleOptionClick(e) {
const btn = e.currentTarget;
if (isAnswered || isGameOver) return;
if (btn.disabled) return;
const selectedIndex = parseInt(btn.dataset.index);
const q = currentQuestions[currentIndex];
const isCorrect = (selectedIndex === q.ans);
isAnswered = true;
optionBtns.forEach(b => { b.disabled = true;
b.style.pointerEvents = 'none'; });
optionBtns.forEach((b, idx) => {
if (idx === q.ans) {
b.classList.add('correct');
} else if (idx === selectedIndex && !isCorrect) {
b.classList.add('wrong');
}
});
let addScore = 0;
if (isCorrect) {
combo++;
if (combo > maxCombo) maxCombo = combo;
let bonus = Math.floor(combo / 3) * 2;
let diffMultiplier = currentDifficulty;
addScore = Math.round((10 + bonus) * diffMultiplier);
score += addScore;
correctCount++;
difficultyUnlockCount++;
// 连续答对5题奖励10秒
if (combo % 5 === 0) {
timeLeft += 10;
showFloatScore('⏱️ +10秒!', '#3498db');
updateTimerUI();
}
if (difficultyUnlockCount >= 10 && currentDifficulty < 3) {
currentDifficulty++;
difficultyUnlockCount = 0;
showFloatScore('🌟 解锁难度 ' + currentDifficulty + '!', '#9b59b6');
updateDifficultyUI();
}
feedbackText.textContent = '✅ ' + q.exp;
feedbackText.className = 'correct';
playCorrectSound();
flashScreen(true);
showFloatScore('+' + addScore, '#2ecc71');
} else {
combo = 0;
lives--;
score -= 5;
wrongCount++;
feedbackText.textContent = '❌ 正确答案是:' + q.opts[q.ans] + '。' + q.exp;
feedbackText.className = 'wrong';
playWrongSound();
flashScreen(false);
showFloatScore('-5', '#e74c3c');
if (lives <= 0) {
setTimeout(() => endGame(), 600);
return;
}
}
updateScoreUI();
updateComboUI();
updateLivesUI();
checkAchievements();
setTimeout(() => {
if (isGameOver) return;
currentIndex++;
if (currentIndex >= currentQuestions.length) {
endGame();
} else {
showQuestion(currentIndex);
}
}, 1200);
}
function startTimer() {
if (timerInterval) clearInterval(timerInterval);
timerInterval = setInterval(() => {
timeLeft -= 0.1;
if (timeLeft < 0) timeLeft = 0;
updateTimerUI();
if (timeLeft <= 0) {
clearInterval(timerInterval);
timerInterval = null;
endGame();
}
}, 100);
}
function endGame() {
if (isGameOver) return;
isGameOver = true;
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
optionBtns.forEach(b => { b.disabled = true;
b.style.pointerEvents = 'none'; });
let timeBonus = Math.floor(timeLeft * 0.5);
score += timeBonus;
if (score > highScore) {
highScore = score;
localStorage.setItem('quizEnhancedHighScore', String(highScore));
}
updateHighScoreDisplay();
finalScoreText.textContent = score + ' 分';
finalHighScore.textContent = highScore;
correctCountEl.textContent = correctCount;
wrongCountEl.textContent = wrongCount;
maxComboEl.textContent = maxCombo;
finalDifficultyEl.textContent = currentDifficulty;
const achList = achievementList;
achList.innerHTML = '';
achievementDefs.forEach(def => {
const span = document.createElement('span');
span.className = 'ach-item';
span.textContent = achievements.includes(def.id) ? '✅ ' + def.name : '⬜ ' + def.name;
achList.appendChild(span);
});
gameOverOverlay.style.display = 'flex';
}
function startGame() {
// 从全部题库中随机抽取 30~40 道题,并打乱顺序
const shuffledAll = [...baseQuestions].sort(() => Math.random() - 0.5);
const take = Math.min(30 + Math.floor(Math.random() * 11), shuffledAll.length); // 30~40题
const selected = shuffledAll.slice(0, take);
// 再打乱一次
currentQuestions = selected.sort(() => Math.random() - 0.5);
currentIndex = 0;
score = 0;
correctCount = 0;
wrongCount = 0;
combo = 0;
maxCombo = 0;
lives = maxLives;
timeLeft = maxTime;
currentDifficulty = 1;
difficultyUnlockCount = 0;
achievements = [];
isGameOver = false;
isAnswered = false;
updateScoreUI();
updateTimerUI();
updateComboUI();
updateLivesUI();
updateDifficultyUI();
gameOverOverlay.style.display = 'none';
selectScreen.style.display = 'none';
gameScreen.style.display = 'flex';
showQuestion(0);
startTimer();
}
function goToSelect() {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
isGameOver = true;
gameOverOverlay.style.display = 'none';
gameScreen.style.display = 'none';
selectScreen.style.display = 'flex';
updateHighScoreDisplay();
optionBtns.forEach(b => {
b.className = 'option-btn';
b.disabled = false;
b.style.pointerEvents = 'auto';
});
feedbackText.textContent = '💡 选择一个答案吧!';
feedbackText.className = '';
}
function restartSameGame() {
gameOverOverlay.style.display = 'none';
startGame();
}
function saveScore() {
const name = playerNameInput.value.trim() || '玩家';
let leaderboard = JSON.parse(localStorage.getItem('quizLeaderboard')) || [];
leaderboard.push({ name, score });
leaderboard.sort((a, b) => b.score - a.score);
if (leaderboard.length > 5) leaderboard = leaderboard.slice(0, 5);
localStorage.setItem('quizLeaderboard', JSON.stringify(leaderboard));
alert('✅ 已保存到排行榜!');
}
// ---------- 事件绑定 ----------
optionBtns.forEach(btn => btn.addEventListener('click', handleOptionClick));
startBtn.addEventListener('click', startGame);
backBtn.addEventListener('click', goToSelect);
resetBtn.addEventListener('click', goToSelect);
gameoverBack.addEventListener('click', goToSelect);
restartSame.addEventListener('click', restartSameGame);
saveScoreBtn.addEventListener('click', saveScore);
// 键盘快捷键
document.addEventListener('keydown', (e) => {
const key = e.key;
if (['1', '2', '3', '4'].includes(key)) {
const idx = parseInt(key) - 1;
if (idx < optionBtns.length) {
optionBtns[idx].click();
}
}
if (key === 'Enter' || key === ' ') {
if (!isGameOver && !isAnswered) {
for (let b of optionBtns) {
if (!b.disabled) {
b.click();
break;
}
}
}
}
});
// ---------- 初始化 ----------
updateHighScoreDisplay();
selectScreen.style.display = 'flex';
gameScreen.style.display = 'none';
document.getElementById('total-q-count').textContent = baseQuestions.length;
qTotal.textContent = baseQuestions.length;
})();
</script>
</body>
</html>Game Source: 垃圾小卫士 · 知识大挑战
Creator: MysticLion44
Libraries: none
Complexity: complex (715 lines, 55.5 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-mysticlion44-mrapia6u" to link back to the original. Then publish at arcadelab.ai/publish.