<!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>
/* ================= 基础重置与全局样式 ================= */
:root {
--primary: #667eea;
--primary-dark: #5a67d8;
--accent: #ff9f43;
--success: #2ecc71;
--error: #ff6b6b;
--bg-color: #f4f7f6;
--card-bg: #ffffff;
--text-main: #2d3436;
--text-sub: #636e72;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
::-webkit-scrollbar { display: none; }
html, body { margin: 0; padding: 0; background: var(--bg-color); overflow: hidden; height: 100vh; }
/* 动态背景图案 */
body {
background-image: radial-gradient(#e0e0e0 1px, transparent 1px);
background-size: 20px 20px;
}
#app { height: 100vh; max-width: 480px; margin: 0 auto; background: rgba(255,255,255,0.95); display: flex; flex-direction: column; position: relative; box-shadow: 0 0 30px rgba(0,0,0,0.05); }
.content-area { flex: 1; overflow-y: auto; padding-bottom: 90px; scroll-behavior: smooth; padding-top: 10px; }
/* 通用动画类 */
.fade-in { animation: fadeIn 0.4s ease-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.shake { animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes shake { 10%, 90% { transform: translate3d(-1px, 0, 0); } 20%, 80% { transform: translate3d(2px, 0, 0); } 30%, 50%, 70% { transform: translate3d(-4px, 0, 0); } 40%, 60% { transform: translate3d(4px, 0, 0); } }
/* ================= 底部导航 (App Bar) ================= */
.bottom-nav {
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
width: 100%; max-width: 480px; height: 75px;
background: rgba(255, 255, 255, 0.98);
border-top: 1px solid rgba(0,0,0,0.05);
display: flex; justify-content: space-around; align-items: center;
z-index: 9999; box-shadow: 0 -5px 20px rgba(0,0,0,0.03);
backdrop-filter: blur(10px);
padding-bottom: 10px; /* 适配全面屏手势区 */
}
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; cursor: pointer; padding: 5px; color: #b2bec3; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); }
.nav-item.active { color: var(--primary); transform: translateY(-5px); }
.nav-icon { font-size: 22px; margin-bottom: 2px; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1)); }
.nav-label { font-size: 10px; font-weight: 600; }
/* ================= 顶部 Tab 导航 ================= */
.tab-nav {
display: flex; background: white; margin: 10px 20px 20px;
border-radius: 12px; padding: 5px; box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
font-weight: 600; color: var(--text-sub); border-radius: 8px;
transition: all 0.3s; font-size: 14px;
}
.tab-item.active { background: #e0e7ff; color: var(--primary); }
/* ================= 演示区域 (SVG) ================= */
.demo-page { padding: 0 15px; }
.animation-area {
background: #ffffff;
border-radius: 20px; padding: 10px; height: 320px;
position: relative; overflow: hidden;
box-shadow: inset 0 0 20px rgba(0,0,0,0.03), 0 10px 20px rgba(0,0,0,0.05);
border: 1px solid rgba(0,0,0,0.05);
}
.svg-container { width: 100%; height: 100%; }
/* 步骤控制器 */
.step-controls {
position: absolute; top: 50%; width: 100%; left: 0;
display: flex; justify-content: space-between; padding: 0 10px;
transform: translateY(-50%); z-index: 10; pointer-events: none;
}
.step-controls button {
pointer-events: auto; width: 44px; height: 44px;
background: rgba(255, 255, 255, 0.9); color: var(--primary);
border: 1px solid rgba(0,0,0,0.1); border-radius: 50%;
font-size: 18px; cursor: pointer; box-shadow: 0 4px 10px rgba(0,0,0,0.1);
transition: all 0.2s; display: flex; align-items: center; justify-content: center;
}
.step-controls button:active { transform: scale(0.9); }
.step-controls button:disabled { opacity: 0; pointer-events: none; }
/* 公式区 */
.math-area {
background: #fff; border-left: 4px solid var(--primary);
border-radius: 0 12px 12px 0; padding: 15px; margin: 15px 0;
min-height: 80px; display: flex; align-items: center; justify-content: center;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.math-formula { font-size: 22px; font-weight: 800; color: var(--text-main); text-align: center; }
.step-explanation {
background: #eef2ff; padding: 12px 15px; border-radius: 12px;
color: var(--primary-dark); font-size: 15px; text-align: center;
line-height: 1.5; font-weight: 500;
}
/* ================= 概念页 ================= */
.intro-page { padding: 30px 20px; text-align: center; }
.concept-emoji { font-size: 80px; margin-bottom: 20px; animation: float 3s ease-in-out infinite; }
@keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-10px); } 100% { transform: translateY(0px); } }
.concept-title { font-size: 28px; font-weight: 800; color: var(--text-main); margin-bottom: 20px; letter-spacing: 1px; }
.concept-story {
background: #fff; padding: 25px; border-radius: 20px; text-align: left;
font-size: 16px; line-height: 1.8; color: var(--text-sub);
box-shadow: 0 10px 25px rgba(0,0,0,0.05); margin-bottom: 25px;
}
.concept-list { text-align: left; background: #fff; padding: 20px; border-radius: 16px; box-shadow: 0 5px 15px rgba(0,0,0,0.03); border: 1px solid rgba(0,0,0,0.03); }
.concept-list li { margin-bottom: 12px; line-height: 1.6; position: relative; padding-left: 5px; }
.listen-btn {
background: linear-gradient(135deg, var(--primary) 0%, #a29bfe 100%);
color: white; border: none; padding: 16px 45px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer;
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
transition: all 0.2s; position: relative; overflow: hidden;
}
.listen-btn:active { transform: scale(0.95); box-shadow: 0 4px 10px rgba(102, 126, 234, 0.3); }
/* ================= 讲解页 (手风琴) ================= */
.explain-page { padding: 20px; }
.example-card {
background: white; border-radius: 16px; padding: 20px; margin-bottom: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.04); transition: transform 0.2s;
}
.example-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.example-type {
background: #e0e7ff; color: var(--primary); padding: 4px 12px;
border-radius: 20px; font-size: 12px; font-weight: 700;
}
.toggle-btn {
background: transparent; color: var(--text-sub); border: 1px solid #e0e0e0;
padding: 6px 15px; border-radius: 20px; cursor: pointer; font-size: 13px;
}
.example-question { font-size: 17px; font-weight: 600; color: var(--text-main); margin: 15px 0; line-height: 1.5; }
.example-answer {
background: #f8fafc; padding: 20px; border-radius: 12px; margin-top: 15px;
font-size: 15px; line-height: 1.8; color: var(--text-sub); border-left: 3px solid var(--accent);
}
/* ================= 练习与奥数 ================= */
.practice-page { padding: 20px; }
.question-card {
background: white; border-radius: 24px; padding: 30px 20px;
box-shadow: 0 15px 35px rgba(0,0,0,0.08);
}
.question-header {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 25px; border-bottom: 2px solid #f0f2f5; padding-bottom: 15px;
}
.score-display {
background: #fff3e0; color: #ff9800; padding: 5px 15px;
border-radius: 20px; font-weight: 800; font-size: 14px;
}
.question-text { font-size: 19px; line-height: 1.6; color: var(--text-main); margin-bottom: 30px; font-weight: 600; }
.option-btn {
display: flex; align-items: center; width: 100%; padding: 18px; margin-bottom: 15px;
text-align: left; border: 2px solid #f0f2f5; border-radius: 16px;
background: white; font-size: 17px; cursor: pointer; color: var(--text-sub);
transition: all 0.2s; position: relative; overflow: hidden;
}
.option-btn:active:not(:disabled) { transform: scale(0.98); background: #fafafa; }
.option-btn.correct { background: #eafff3; border-color: #2ecc71; color: #2ecc71; font-weight: 600; }
.option-btn.wrong { background: #fff5f5; border-color: #ff6b6b; color: #ff6b6b; }
/* 错题震动效果 */
.option-btn.shaking { animation: shake 0.5s; }
.feedback-area {
padding: 20px; border-radius: 16px; margin: 25px 0;
font-size: 15px; line-height: 1.6; animation: fadeIn 0.3s ease;
}
.feedback-correct { background: #eafff3; color: #27ae60; border: 1px solid #b8e9ca; }
.feedback-wrong { background: #fff5f5; color: #c0392b; border: 1px solid #ffcccc; }
.next-btn {
width: 100%; padding: 18px;
background: linear-gradient(135deg, var(--primary) 0%, #764ba2 100%);
color: white; border: none; border-radius: 16px;
font-size: 18px; font-weight: bold; cursor: pointer;
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
transition: transform 0.2s;
}
.next-btn:active { transform: scale(0.97); }
.hint-box { background: #fff8e1; border-left: 5px solid #ffca28; padding: 15px; border-radius: 8px; margin: 15px 0; font-size: 14px; color: #f57c00; font-weight: 500; }
.difficulty-badge {
padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: 700; margin-left: 8px;
vertical-align: middle;
}
.difficulty-1 { background: #e8f5e9; color: #2e7d32; }
.difficulty-2 { background: #fff3e0; color: #ef6c00; }
.difficulty-3 { background: #ffebee; color: #c62828; }
/* ================= 秘籍页 ================= */
.secrets-container { padding: 30px 20px; overflow-x: auto; padding-bottom: 50px; }
.secrets-scroll { display: flex; gap: 20px; }
.secret-card {
flex: 0 0 auto; width: 280px; height: 360px;
border-radius: 30px; padding: 30px;
display: flex; flex-direction: column; justify-content: center; align-items: center;
color: white; text-align: center; position: relative; overflow: hidden;
box-shadow: 0 15px 35px rgba(0,0,0,0.15); transition: transform 0.3s;
}
.secret-card:active { transform: scale(0.98); }
/* 给卡片加一点装饰纹理 */
.secret-card::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 60%); pointer-events: none; }
.secret-icon { font-size: 80px; margin-bottom: 30px; filter: drop-shadow(0 5px 10px rgba(0,0,0,0.2)); }
.secret-title { font-size: 24px; font-weight: 800; margin-bottom: 20px; }
.secret-content { font-size: 16px; line-height: 1.6; opacity: 0.95; }
/* 完成页 */
.completion-page { text-align: center; padding: 80px 20px; }
.final-score { font-size: 72px; font-weight: 800; color: var(--accent); margin-bottom: 40px; text-shadow: 4px 4px 0px rgba(0,0,0,0.1); }
.restart-btn {
background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
color: white; border: none; padding: 18px 50px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer; box-shadow: 0 10px 20px rgba(0,184,148,0.3);
}
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="intro-page fade-in">
<div class="concept-emoji">🎈</div>
<div class="concept-title">简单的排队问题</div>
<div class="concept-story">
<p>操场上,老师让小朋友们排队。乐乐想知道:“我前面有3个人,后面有4个人,我们这一队一共有多少人呢?”</p>
<p>这和我们平时数糖果、数玩具可不太一样。今天我们就来学习排队里的数学秘密!</p>
</div>
<div class="concept-list">
<div style="font-weight: bold; color: var(--primary); margin-bottom: 10px;">🌟 核心概念:</div>
<ul>
<li><strong>基数</strong>:数有多少个 (1个, 2个...)</li>
<li><strong>序数</strong>:排第几名 (第1, 第2...)</li>
<li><strong>重叠问题</strong>:别把同一个人数了两次哦!</li>
</ul>
</div>
<button class="listen-btn" @click="speak('小朋友们排队的时候,你是排第几个呢?这和一共有几个人是不一样的哦!')">🎧 听老师讲解</button>
</div>
<div v-show="currentPage === 2" class="demo-page fade-in">
<div class="tab-nav">
<div class="tab-item" :class="{active: demoTab === 'example1'}" @click="switchDemoTab('example1')">排队问题</div>
<div class="tab-item" :class="{active: demoTab === 'example2'}" @click="switchDemoTab('example2')">楼层问题</div>
<div class="tab-item" :class="{active: demoTab === 'example3'}" @click="switchDemoTab('example3')">间隔问题</div>
</div>
<div v-show="demoTab === 'example1'">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330" id="demo-svg-queue">
<rect x="0" y="0" width="400" height="330" fill="none"/>
<line x1="50" y1="200" x2="350" y2="200" stroke="#dfe6e9" stroke-width="4" stroke-linecap="round"/>
<g v-for="(child, index) in frontChildren" :key="'front'+index">
<circle :cx="child.cx" :cy="child.cy" :r="child.r" :fill="child.fill" stroke="white" stroke-width="3" :id="'front-circle-'+index" style="filter: drop-shadow(0 3px 3px rgba(0,0,0,0.1));"/>
<text :x="child.cx" :y="child.cy+5" text-anchor="middle" font-size="16" font-weight="bold" fill="white">{{child.num}}</text>
<text :x="child.cx" :y="child.cy+child.r+25" text-anchor="middle" font-size="12" fill="#b2bec3" :id="'front-label-'+index" font-weight="bold">前{{index+1}}</text>
</g>
<circle cx="200" cy="200" r="28" fill="#ff7675" stroke="white" stroke-width="4" id="me-circle" style="filter: drop-shadow(0 5px 5px rgba(255,118,117,0.4));"/>
<text x="200" y="207" text-anchor="middle" font-size="18" font-weight="bold" fill="white">我</text>
<g v-for="(child, index) in backChildren" :key="'back'+index">
<circle :cx="child.cx" :cy="child.cy" :r="child.r" :fill="child.fill" stroke="white" stroke-width="3" :id="'back-circle-'+index" style="filter: drop-shadow(0 3px 3px rgba(0,0,0,0.1));"/>
<text :x="child.cx" :y="child.cy+5" text-anchor="middle" font-size="16" font-weight="bold" fill="white">{{child.num}}</text>
<text :x="child.cx" :y="child.cy+child.r+25" text-anchor="middle" font-size="12" fill="#b2bec3" :id="'back-label-'+index" font-weight="bold">后{{index+1}}</text>
</g>
<text x="200" y="300" text-anchor="middle" font-size="26" font-weight="800" fill="#6c5ce7" opacity="0" id="formula-text">3 + 1 + 4 = 8 人</text>
</svg>
<div class="step-controls">
<button @click="prevQueueStep" :disabled="queueStep === 0">◀</button>
<button @click="nextQueueStep" :disabled="queueStep === 4">▶</button>
</div>
</div>
<div class="math-area"><div class="math-formula" id="queue-formula">{{queueFormulas[queueStep]}}</div></div>
<div class="step-explanation" id="queue-explanation">{{queueExplanations[queueStep]}}</div>
</div>
<div v-show="demoTab === 'example2'">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330" id="demo-svg-floor">
<rect x="0" y="0" width="400" height="330" fill="none"/>
<g v-for="(floor, index) in floors" :key="'floor'+index">
<rect :x="floor.x" :y="floor.y" :width="floor.width" :height="floor.height" :fill="floor.fill" rx="8" :id="'floor-rect-'+index"/>
<text :x="floor.x+20" :y="floor.y+32" font-size="18" font-weight="900" fill="#fff" style="filter: drop-shadow(0 2px 2px rgba(0,0,0,0.1));">{{floor.label}}F</text>
<text v-if="index < floors.length-1" :x="floor.x+120" :y="floor.y+floor.height+22" font-size="12" fill="#fdcb6e" :id="'stair-label-'+index" opacity="0" font-weight="bold">⚡ 爬楼梯</text>
</g>
<circle cx="160" cy="230" r="14" fill="#ff7675" stroke="white" stroke-width="3" id="person-dot" opacity="0" style="filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));"/>
<text x="200" y="300" text-anchor="middle" font-size="24" font-weight="800" fill="#0984e3" opacity="0" id="floor-formula-text">4 - 1 = 3 层</text>
</svg>
<div class="step-controls">
<button @click="prevFloorStep" :disabled="floorStep === 0">◀</button>
<button @click="nextFloorStep" :disabled="floorStep === 5">▶</button>
</div>
</div>
<div class="math-area"><div class="math-formula" id="floor-formula">{{floorFormulas[floorStep]}}</div></div>
<div class="step-explanation" id="floor-explanation">{{floorExplanations[floorStep]}}</div>
</div>
<div v-show="demoTab === 'example3'">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330" id="demo-svg-interval">
<rect x="0" y="0" width="400" height="330" fill="none"/>
<line x1="50" y1="220" x2="350" y2="220" stroke="#b2bec3" stroke-width="4" stroke-linecap="round"/>
<g v-for="(post, index) in posts" :key="'post'+index">
<rect :x="post.x" :y="post.y" :width="post.width" :height="post.height" :fill="post.fill" rx="4" :id="'post-rect-'+index" style="filter: drop-shadow(2px 2px 0px rgba(0,0,0,0.1));"/>
<text :x="post.x+post.width/2" :y="post.y-10" text-anchor="middle" font-size="12" font-weight="bold" fill="#636e72">{{index+1}}</text>
</g>
<g v-for="(gap, index) in gaps" :key="'gap'+index">
<rect :x="gap.x" :y="gap.y" :width="gap.width" :height="gap.height" fill="#74b9ff" rx="4" :id="'gap-rect-'+index" opacity="0"/>
<text :x="gap.x+gap.width/2" :y="gap.y+gap.height+20" text-anchor="middle" font-size="12" fill="#0984e3" :id="'gap-label-'+index" opacity="0" font-weight="bold">间隔{{index+1}}</text>
</g>
<text x="200" y="300" text-anchor="middle" font-size="24" font-weight="800" fill="#00b894" opacity="0" id="interval-formula-text">5 - 1 = 4 个间隔</text>
</svg>
<div class="step-controls">
<button @click="prevIntervalStep" :disabled="intervalStep === 0">◀</button>
<button @click="nextIntervalStep" :disabled="intervalStep === 3">▶</button>
</div>
</div>
<div class="math-area"><div class="math-formula" id="interval-formula">{{intervalFormulas[intervalStep]}}</div></div>
<div class="step-explanation" id="interval-explanation">{{intervalExplanations[intervalStep]}}</div>
</div>
</div>
<div v-show="currentPage === 3" class="explain-page fade-in">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'basic'}" @click="explainTab = 'basic'">基础概念</div>
<div class="tab-item" :class="{active: explainTab === 'advanced'}" @click="explainTab = 'advanced'">进阶思路</div>
<div class="tab-item" :class="{active: explainTab === 'tricky'}" @click="explainTab = 'tricky'">易错提醒</div>
</div>
<div v-show="explainTab === 'basic'">
<div class="example-card">
<div class="example-header">
<div class="example-type">基础题</div>
<button class="toggle-btn" @click="toggleExample(0)">{{exampleOpen[0] ? '收起' : '查看解析'}}</button>
</div>
<div class="example-question">题目:小朋友排队,小明前面有5人,小明排第几?</div>
<div v-if="exampleOpen[0]" class="example-answer fade-in">
<strong style="color:var(--primary)">答案:第6个</strong><br><br>
解析:<br>1. 前面有5人 = 1,2,3,4,5<br>2. 小明是第5个后面的那个<br>3. 5 + 1 = 6
</div>
</div>
</div>
<div v-show="explainTab === 'advanced'">
<div class="example-card">
<div class="example-header">
<div class="example-type">进阶题</div>
<button class="toggle-btn" @click="toggleExample(1)">{{exampleOpen[1] ? '收起' : '查看解析'}}</button>
</div>
<div class="example-question">题目:小红前面有3人,后面有4人,一共多少人?</div>
<div v-if="exampleOpen[1]" class="example-answer fade-in">
<strong style="color:var(--primary)">答案:8人</strong><br><br>
解析:<br>1. 前面3人<br>2. <span style="color:var(--error);font-weight:bold;">小红自己1人</span> (容易忘!)<br>3. 后面4人<br>4. 3 + 1 + 4 = 8人
</div>
</div>
</div>
<div v-show="explainTab === 'tricky'">
<div class="example-card">
<div class="example-header">
<div class="example-type" style="background:#ffebee;color:#c62828;">易错题</div>
<button class="toggle-btn" @click="toggleExample(2)">{{exampleOpen[2] ? '收起' : '查看解析'}}</button>
</div>
<div class="example-question">题目:从1楼走到4楼,要爬几层楼梯?</div>
<div v-if="exampleOpen[2]" class="example-answer fade-in">
<strong style="color:var(--primary)">答案:3层</strong><br><br>
解析:<br>⚠ 很多小朋友会说爬4层,其实是3层<br>1楼→2楼 (1层)<br>2楼→3楼 (1层)<br>3楼→4楼 (1层)<br>一共:3层 (4-1=3)
</div>
</div>
</div>
</div>
<div v-show="currentPage === 4" class="practice-page fade-in">
<div v-if="!practiceCompleted">
<div class="question-card">
<div class="question-header">
<div class="question-number">第 {{currentQuestion + 1}} / {{practiceQuestions.length}} 题</div>
<div class="score-display">⭐ {{score}}</div>
</div>
<div class="question-text" v-html="practiceQuestions[currentQuestion].text"></div>
<div class="options-container">
<button v-for="(option, index) in practiceQuestions[currentQuestion].options"
:key="'opt'+index"
class="option-btn"
:class="{
'correct': answered && option.correct,
'wrong': answered && selectedOption === index && !option.correct,
'shaking': answered && selectedOption === index && !option.correct && shakingIndex === index
}"
@click="selectOption(index, option.correct)"
:disabled="answered">
<span style="margin-right:10px;font-weight:bold;">{{['A','B','C','D'][index]}}.</span> {{option.text}}
</button>
</div>
<div v-if="answered" class="feedback-area fade-in" :class="isCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isCorrect"><strong>🎉 太棒了!</strong><br>{{practiceQuestions[currentQuestion].explanation}}</div>
<div v-else><strong>💡 再想一想:</strong><br>{{practiceQuestions[currentQuestion].explanation}}</div>
</div>
<button v-if="answered" class="next-btn fade-in" @click="nextQuestion">{{currentQuestion < practiceQuestions.length - 1 ? '下一题 →' : '完成练习'}}</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">🎉</div>
<div class="completion-title">练习完成!</div>
<div class="final-score">+{{score}}</div>
<button class="restart-btn" @click="switchPage(5)">挑战奥数题 🚀</button>
</div>
</div>
<div v-show="currentPage === 5" class="practice-page fade-in">
<div v-if="!olympiadCompleted">
<div class="question-card" style="border: 2px solid #ffd700;">
<div class="question-header">
<div>
<span class="question-number">奥数题 {{currentOlympiad + 1}} / {{olympiadQuestions.length}}</span>
<span class="difficulty-badge" :class="'difficulty-' + olympiadQuestions[currentOlympiad].difficulty">{{olympiadQuestions[currentOlympiad].difficultyText}}</span>
</div>
<div class="score-display">🏆 {{olympiadScore}}</div>
</div>
<div class="question-text" v-html="olympiadQuestions[currentOlympiad].text"></div>
<div class="options-container">
<button v-for="(option, index) in olympiadQuestions[currentOlympiad].options"
:key="'olopt'+index"
class="option-btn"
:class="{
'correct': olympiadAnswered && option.correct,
'wrong': olympiadAnswered && selectedOlympiadOption === index && !option.correct,
'shaking': shakingIndex === index
}"
@click="selectOlympiadOption(index, option.correct)"
:disabled="olympiadAnswered">
<span style="margin-right:10px;font-weight:bold;">{{['A','B','C','D'][index]}}.</span> {{option.text}}
</button>
</div>
<div v-if="wrongAttempts > 0 && !olympiadAnswered">
<div class="hint-box fade-in"><strong>💡 提示:</strong> {{wrongAttempts === 1 ? olympiadQuestions[currentOlympiad].hint1 : olympiadQuestions[currentOlympiad].hint2}}</div>
</div>
<div v-if="olympiadAnswered" class="feedback-area fade-in" :class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isOlympiadCorrect"><strong>🏆 厉害!</strong><br><span v-html="olympiadQuestions[currentOlympiad].explanation"></span></div>
<div v-else><strong>📖 解析:</strong><br><span v-html="olympiadQuestions[currentOlympiad].explanation"></span></div>
</div>
<button v-if="olympiadAnswered || wrongAttempts >= 3" class="next-btn fade-in" @click="nextOlympiad">{{currentOlympiad < olympiadQuestions.length - 1 ? '下一关 →' : '完成挑战'}}</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">🏆</div>
<div class="completion-title">奥数通关!</div>
<div class="final-score">{{olympiadScore}}</div>
<button class="restart-btn" @click="switchPage(6)">查看通关秘籍 🎁</button>
</div>
</div>
<div v-show="currentPage === 6" class="secrets-container fade-in">
<div class="secrets-scroll">
<div class="secret-card" style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); color:#555;">
<div class="secret-icon">🖼️</div>
<div class="secret-title">画图大法</div>
<div class="secret-content">遇到排队问题,千万别空想。<br>画个圈圈代表小朋友,一目了然!</div>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); color:#555;">
<div class="secret-icon">👆</div>
<div class="secret-title">别忘自己</div>
<div class="secret-content">问“一共有多少人”时,<br>一定要看看有没有加上<br>“我自己”!</div>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #e0c3fc 0%, #8ec5fc 100%); color:#555;">
<div class="secret-icon">📏</div>
<div class="secret-title">减1法则</div>
<div class="secret-content">爬楼梯、种树、锯木头...<br>通常都要减1哦!<br>(间隔数 = 物体数 - 1)</div>
</div>
</div>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item" :class="{active: currentPage === 1}" @click="switchPage(1)">
<div class="nav-icon">💡</div><div class="nav-label">概念</div>
</div>
<div class="nav-item" :class="{active: currentPage === 2}" @click="switchPage(2)">
<div class="nav-icon">🎬</div><div class="nav-label">演示</div>
</div>
<div class="nav-item" :class="{active: currentPage === 3}" @click="switchPage(3)">
<div class="nav-icon">📝</div><div class="nav-label">讲解</div>
</div>
<div class="nav-item" :class="{active: currentPage === 4}" @click="switchPage(4)">
<div class="nav-icon">✏️</div><div class="nav-label">练习</div>
</div>
<div class="nav-item" :class="{active: currentPage === 5}" @click="switchPage(5)">
<div class="nav-icon">🏆</div><div class="nav-label">奥数</div>
</div>
<div class="nav-item" :class="{active: currentPage === 6}" @click="switchPage(6)">
<div class="nav-icon">🎁</div><div class="nav-label">秘籍</div>
</div>
</div>
</div>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/vue.global.prod.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/gsap.min.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/confetti.browser.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
demoTab: 'example1',
explainTab: 'basic',
queueStep: 0,
floorStep: 0,
intervalStep: 0,
exampleOpen: [false, false, false],
// 新增:错题震动控制
shakingIndex: null,
// 演示数据 - 优化颜色
frontChildren: [
{cx: 110, cy: 200, r: 20, fill: '#74b9ff', num: 1},
{cx: 140, cy: 200, r: 20, fill: '#a29bfe', num: 2},
{cx: 170, cy: 200, r: 20, fill: '#81ecec', num: 3}
],
backChildren: [
{cx: 230, cy: 200, r: 20, fill: '#fab1a0', num: 1},
{cx: 260, cy: 200, r: 20, fill: '#ff7675', num: 2},
{cx: 290, cy: 200, r: 20, fill: '#ffeaa7', num: 3},
{cx: 320, cy: 200, r: 20, fill: '#55efc4', num: 4}
],
queueFormulas: ['', '前面3人', '前面3人 + 我', '前面3人 + 我 + 后面4人', '3 + 1 + 4 = 8 人'],
queueExplanations: ['点击右箭头开始演示 👉', '小红前面有3个小朋友', '⭐ 别忘了小红自己 (1人)', '小红后面还有4个小朋友', '所有人加起来:3 + 1 + 4 = 8人'],
floors: [
{x: 110, y: 240, width: 180, height: 50, fill: '#81ecec', label: '1'},
{x: 110, y: 180, width: 180, height: 50, fill: '#74b9ff', label: '2'},
{x: 110, y: 120, width: 180, height: 50, fill: '#0984e3', label: '3'},
{x: 110, y: 60, width: 180, height: 50, fill: '#6c5ce7', label: '4'}
],
floorFormulas: ['', '出发!', '1楼 → 2楼 (1层)', '2楼 → 3楼 (2层)', '3楼 → 4楼 (3层)', '爬了 N-1 层'],
floorExplanations: ['点击右箭头开始演示 👉', '小红从1楼出发去4楼', '爬了第1层楼梯,到达2楼', '爬了第2层楼梯,到达3楼', '爬了第3层楼梯,到达4楼', '虽然是4楼,但只爬了 4-1=3 层楼梯哦!'],
posts: [
{x: 70, y: 120, width: 20, height: 100, fill: '#b2bec3'},
{x: 120, y: 120, width: 20, height: 100, fill: '#b2bec3'},
{x: 170, y: 120, width: 20, height: 100, fill: '#b2bec3'},
{x: 220, y: 120, width: 20, height: 100, fill: '#b2bec3'},
{x: 270, y: 120, width: 20, height: 100, fill: '#b2bec3'}
],
gaps: [
{x: 90, y: 160, width: 30, height: 40},
{x: 140, y: 160, width: 30, height: 40},
{x: 190, y: 160, width: 30, height: 40},
{x: 240, y: 160, width: 30, height: 40}
],
intervalFormulas: ['', '5根栏杆', '栏杆之间有空隙', '数一数有几个', '间隔数 = 5 - 1'],
intervalExplanations: ['点击右箭头开始演示 👉', '路边有5根灰色的栏杆', '每两根栏杆中间,都有一个“间隔”', '1, 2, 3, 4... 一共有4个间隔', '5根栏杆有4个间隔。间隔数总是比物体数少1。'],
// 练习与奥数数据保持原逻辑
practiceQuestions: [
{text: '排队买票,小明排第8,他前面有几人?', options: [{text: '7人', correct: true}, {text: '8人', correct: false}, {text: '9人', correct: false}, {text: '6人', correct: false}], explanation: '排第8,说明前面有第1到第7,一共7人。前面的人数=排号-1=8-1=7人'},
{text: '小朋友排队,小刚前面有4人,小刚排第几?', options: [{text: '第3', correct: false}, {text: '第4', correct: false}, {text: '第5', correct: true}, {text: '第6', correct: false}], explanation: '前面有4人,小刚是第5个。前面人数+1=排的位置,4+1=5,排第5'},
{text: '爬楼梯,从2楼到5楼,要爬几层?', options: [{text: '2层', correct: false}, {text: '3层', correct: true}, {text: '4层', correct: false}, {text: '5层', correct: false}], explanation: '数一数:2→3(第1层),3→4(第2层),4→5(第3层)。或者用公式:5-2=3层'},
{text: '10个小朋友排队,小明排第6,他后面有几人?', options: [{text: '3人', correct: false}, {text: '4人', correct: true}, {text: '5人', correct: false}, {text: '6人', correct: false}], explanation: '总共10人,小明第6,后面的人=总人数-小明的位置=10-6=4人'},
{text: '马路上有6根栏杆,栏杆之间有几个间隔?', options: [{text: '4个', correct: false}, {text: '5个', correct: true}, {text: '6个', correct: false}, {text: '7个', correct: false}], explanation: '画出6根栏杆:| | | | | |,数中间的空隙有5个。间隔数=栏杆数-1=6-1=5个'},
{text: '小红排队,前面有3人,后面有3人,队伍共几人?', options: [{text: '6人', correct: false}, {text: '7人', correct: true}, {text: '8人', correct: false}, {text: '9人', correct: false}], explanation: '别忘了小红自己!前面3+小红1+后面3=7人'},
{text: '排第10的小朋友,和排第3的小朋友之间有几人?', options: [{text: '5人', correct: false}, {text: '6人', correct: true}, {text: '7人', correct: false}, {text: '8人', correct: false}], explanation: '从第3到第10,中间是第4、5、6、7、8、9,共6人。公式:10-3-1=6人'},
{text: '锯木头,把一根木头锯成5段,要锯几次?', options: [{text: '3次', correct: false}, {text: '4次', correct: true}, {text: '5次', correct: false}, {text: '6次', correct: false}], explanation: '画图看看:—|—|—|—|—,数一数“|”有4个(表示锯的次数)。锯成5段要锯4次,段数-1=次数'}
],
olympiadQuestions: [
{text: '小朋友排队拍照,第一排8人,第二排8人,两排之间有2人重叠(站在中间既算第一排也算第二排)。一共有多少人?', options: [{text: '14人', correct: true}, {text: '15人', correct: false}, {text: '16人', correct: false}, {text: '18人', correct: false}], hint1: '两排分别有多少人?', hint2: '直接加起来会重复数哪些人?', hint3: '8+8-2=14人', explanation: '第一排:8人<br>第二排:8人<br>如果简单相加:8+8=16人<br>但有2人重叠(被数了两次)<br>实际人数:16-2=14人', difficulty: 1, difficultyText: '⭐'},
{text: '小明家住6楼,每层楼梯有12个台阶。从1楼走到6楼,一共要爬多少个台阶?', options: [{text: '60个', correct: true}, {text: '72个', correct: false}, {text: '48个', correct: false}, {text: '84个', correct: false}], hint1: '从1楼到6楼要爬几层?', hint2: '6-1=5层', hint3: '5×12=60个台阶', explanation: '从1楼到6楼:爬5层楼梯(不是6层!)<br>每层12个台阶<br>总台阶:5×12=60个', difficulty: 1, difficultyText: '⭐'},
{text: '小朋友围成一圈做游戏,小明左边有5人,右边有4人,一共多少人?', options: [{text: '9人', correct: false}, {text: '10人', correct: true}, {text: '11人', correct: false}, {text: '12人', correct: false}], hint1: '围成圈和排队不一样', hint2: '左边5+小明1+右边4', hint3: '5+1+4=10人', explanation: '围成圈的问题:左边5人+小明1人+右边4人=10人<br>注意:围成圈时左右两边没有重叠', difficulty: 2, difficultyText: '⭐⭐'},
{text: '种树问题:马路一边每隔5米种一棵树,从起点到终点共20米,要种几棵树?(两端都种)', options: [{text: '3棵', correct: false}, {text: '4棵', correct: false}, {text: '5棵', correct: true}, {text: '6棵', correct: false}], hint1: '先算有几个间隔', hint2: '20÷5=4个间隔', hint3: '两端都种:棵数=间隔数+1=5棵', explanation: '总长20米,每隔5米一棵<br>间隔数:20÷5=4个间隔<br>两端都种:树的棵数=间隔数+1=4+1=5棵', difficulty: 2, difficultyText: '⭐⭐'},
{text: '小朋友排队,从左数小明排第7,从右数小明排第5,队伍一共几人?', options: [{text: '10人', correct: false}, {text: '11人', correct: true}, {text: '12人', correct: false}, {text: '13人', correct: false}], hint1: '从左数第7,左边有6人', hint2: '从右数第5,右边有4人', hint3: '6+1+4=11人(小明被数了一次)', explanation: '从左数第7:左边有6人+小明<br>从右数第5:右边有4人+小明<br>总人数:6+1+4=11人<br>或者用公式:左边位置+右边位置-1=7+5-1=11人', difficulty: 2, difficultyText: '⭐⭐'},
{text: '锯木头,锯一次要3分钟。把一根木头锯成6段,要多少分钟?', options: [{text: '12分钟', correct: false}, {text: '15分钟', correct: true}, {text: '18分钟', correct: false}, {text: '21分钟', correct: false}], hint1: '锯成6段要锯几次?', hint2: '6段需要5次(6-1=5)', hint3: '5×3=15分钟', explanation: '锯成6段,需要锯5次(段数-1)<br>每次3分钟<br>总时间:5×3=15分钟', difficulty: 1, difficultyText: '⭐'},
{text: '时钟敲钟,敲5下用了8秒,敲12下要用多少秒?', options: [{text: '16秒', correct: false}, {text: '20秒', correct: false}, {text: '22秒', correct: true}, {text: '24秒', correct: false}], hint1: '敲5下有几个时间间隔?', hint2: '4个间隔用8秒,每个间隔2秒', hint3: '敲12下有11个间隔,11×2=22秒', explanation: '敲5下,有4个间隔(5-1=4)<br>8秒敲4个间隔,每个间隔:8÷4=2秒<br>敲12下,有11个间隔(12-1=11)<br>总时间:11×2=22秒', difficulty: 3, difficultyText: '⭐⭐⭐'},
{text: '围棋盘:在正方形四条边上,每边放8颗棋子(四个角都放),一共放了多少颗?', options: [{text: '28颗', correct: true}, {text: '30颗', correct: false}, {text: '32颗', correct: false}, {text: '36颗', correct: false}], hint1: '每边8颗,四边是多少颗?', hint2: '8×4=32,但角上的被数了两次', hint3: '32-4=28颗', explanation: '每边8颗,四条边:8×4=32颗<br>但是!四个角的棋子被数了两次<br>要减去重复的:32-4=28颗', difficulty: 3, difficultyText: '⭐⭐⭐'}
],
currentQuestion: 0,
answered: false,
selectedOption: null,
isCorrect: false,
score: 0,
practiceCompleted: false,
currentOlympiad: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
wrongAttempts: 0,
olympiadScore: 0,
olympiadCompleted: false
};
},
mounted() {
this.runQueueAnimation();
this.runFloorAnimation();
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
window.scrollTo(0,0); // 切换页面时滚回顶部
if (page === 2) {
this.queueStep = 0;
this.floorStep = 0;
this.intervalStep = 0;
this.$nextTick(() => {
this.runQueueAnimation();
});
}
if (page === 4 && this.practiceCompleted) {
this.resetPractice();
}
if (page === 5 && this.olympiadCompleted) {
this.resetOlympiad();
}
},
stopSpeak() {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
const audio = document.getElementById('tts-audio');
if (audio) {
audio.pause();
audio.currentTime = 0;
}
} else {
if (window.speechSynthesis) {
window.speechSynthesis.cancel();
}
}
},
switchDemoTab(tab) {
this.stopSpeak();
this.demoTab = tab;
this.queueStep = 0;
this.floorStep = 0;
this.intervalStep = 0;
this.$nextTick(() => {
if (tab === 'example1') this.runQueueAnimation();
else if (tab === 'example2') this.runFloorAnimation();
else if (tab === 'example3') this.runIntervalAnimation();
});
},
toggleExample(index) {
this.exampleOpen[index] = !this.exampleOpen[index];
},
speak(text) {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
let audio = document.getElementById('tts-audio');
if (!audio) {
audio = document.createElement('audio');
audio.id = 'tts-audio';
audio.style.display = 'none';
document.body.appendChild(audio);
}
const url = `https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(err => { console.log('语音播放失败:', err); });
} else {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
},
runQueueAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
tl.set('#demo-svg-queue text', {opacity: 0});
tl.set('#demo-svg-queue circle', {opacity: 0});
if (this.queueStep >= 0) {
tl.to('#demo-svg-queue circle', {opacity: 1, duration: 0.5});
tl.to('#demo-svg-queue text', {opacity: 1, duration: 0.5}, '-=0.3');
}
if (this.queueStep >= 1) {
for (let i=0; i<3; i++) {
tl.to(`#front-circle-${i}`, {scale: 1.3, fill: '#fab1a0', duration: 0.3, repeat: 1, yoyo: true}, `+=${i*0.1}`);
}
}
if (this.queueStep >= 2) {
tl.to('#me-circle', {scale: 1.4, fill: '#ff6b6b', duration: 0.5, repeat: 2, yoyo: true}, '+=0.2');
}
if (this.queueStep >= 3) {
for (let i=0; i<4; i++) {
tl.to(`#back-circle-${i}`, {scale: 1.3, fill: '#81ecec', duration: 0.3, repeat: 1, yoyo: true}, `+=${i*0.1}`);
}
}
if (this.queueStep >= 4) {
tl.to('#demo-svg-queue circle', {y: -10, duration: 0.3, repeat: 1, yoyo: true, stagger: 0.1}, '+=0.2');
tl.to('#formula-text', {opacity: 1, duration: 1, scale: 1.2, ease: "elastic.out(1, 0.3)"}, '-=0.5');
}
},
nextQueueStep() {
if (this.queueStep < 4) {
this.queueStep++;
this.runQueueAnimation();
}
},
prevQueueStep() {
if (this.queueStep > 0) {
this.queueStep--;
this.runQueueAnimation();
}
},
runFloorAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
tl.set('#demo-svg-floor text', {opacity: 0});
tl.set('#demo-svg-floor rect', {opacity: 0});
tl.set('#person-dot', {opacity: 0});
if (this.floorStep >= 0) {
tl.to('#demo-svg-floor rect', {opacity: 1, duration: 0.5});
tl.to('#demo-svg-floor text', {opacity: 1, duration: 0.5}, '-=0.3');
}
if (this.floorStep >= 1) {
tl.to('#floor-rect-0', {fill: '#fab1a0', duration: 0.5});
tl.to('#person-dot', {opacity: 1, duration: 0.5}, '-=0.5');
}
if (this.floorStep >= 2) {
tl.to('#person-dot', {cy: 200, duration: 0.8, ease: "power2.inOut"}, '+=0.2');
tl.to('#stair-label-0', {opacity: 1, duration: 0.3}, '-=0.3');
tl.to('#floor-rect-1', {fill: '#74b9ff', duration: 0.5}, '-=0.3');
}
if (this.floorStep >= 3) {
tl.to('#person-dot', {cy: 140, duration: 0.8, ease: "power2.inOut"}, '+=0.2');
tl.to('#stair-label-1', {opacity: 1, duration: 0.3}, '-=0.3');
tl.to('#floor-rect-2', {fill: '#0984e3', duration: 0.5}, '-=0.3');
}
if (this.floorStep >= 4) {
tl.to('#person-dot', {cy: 80, duration: 0.8, ease: "power2.inOut"}, '+=0.2');
tl.to('#stair-label-2', {opacity: 1, duration: 0.3}, '-=0.3');
tl.to('#floor-rect-3', {fill: '#6c5ce7', duration: 0.5}, '-=0.3');
}
if (this.floorStep >= 5) {
tl.to('#floor-formula-text', {opacity: 1, duration: 1, scale: 1.2, ease: "elastic.out(1, 0.3)"}, '+=0.2');
}
},
nextFloorStep() {
if (this.floorStep < 5) {
this.floorStep++;
this.runFloorAnimation();
}
},
prevFloorStep() {
if (this.floorStep > 0) {
this.floorStep--;
this.runFloorAnimation();
}
},
runIntervalAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
tl.set('#demo-svg-interval text', {opacity: 0});
tl.set('#demo-svg-interval rect', {opacity: 0});
if (this.intervalStep >= 0) {
tl.to('#demo-svg-interval rect', {opacity: 1, duration: 0.5});
tl.to('#demo-svg-interval text', {opacity: 1, duration: 0.5}, '-=0.3');
}
if (this.intervalStep >= 2) {
tl.to(`[id^='gap-rect-']`, {opacity: 0.8, duration: 0.3, stagger: 0.1});
}
if (this.intervalStep >= 3) {
tl.to(`[id^='gap-label-']`, {opacity: 1, duration: 0.3, stagger: 0.1});
tl.to('#interval-formula-text', {opacity: 1, duration: 1, scale: 1.2, ease: "elastic.out(1, 0.3)"}, '+=0.3');
}
},
nextIntervalStep() {
if (this.intervalStep < 3) {
this.intervalStep++;
this.runIntervalAnimation();
}
},
prevIntervalStep() {
if (this.intervalStep > 0) {
this.intervalStep--;
this.runIntervalAnimation();
}
},
selectOption(index, correct) {
if (this.answered) return;
if (!correct) {
// 错题震动效果逻辑
this.shakingIndex = index;
setTimeout(() => {
this.shakingIndex = null;
}, 500);
}
this.answered = true;
this.selectedOption = index;
this.isCorrect = correct;
if (correct) {
this.score += 20;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.selectedOption = null;
} else {
this.practiceCompleted = true;
}
},
resetPractice() {
this.currentQuestion = 0;
this.answered = false;
this.selectedOption = null;
this.isCorrect = false;
this.score = 0;
this.practiceCompleted = false;
},
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
if (correct) {
this.selectedOlympiadOption = index;
this.olympiadAnswered = true;
this.isOlympiadCorrect = true;
this.olympiadScore += 30;
this.wrongAttempts = 0;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
}
} else {
// 错题震动
this.shakingIndex = index;
setTimeout(() => { this.shakingIndex = null; }, 500);
this.wrongAttempts++;
if (this.wrongAttempts >= 3) {
this.selectedOlympiadOption = index; // 锁定选择
this.olympiadAnswered = true;
this.isOlympiadCorrect = false;
}
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
},
resetOlympiad() {
this.currentOlympiad = 0;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.wrongAttempts = 0;
this.olympiadScore = 0;
this.olympiadCompleted = false;
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码