Files
RGKT/rg-09112127/html/play/识数小精灵.html

1436 lines
42 KiB
HTML
Raw Normal View History

2025-10-10 19:35:04 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>数字乐园</title>
<!-- 引入后端集成脚本 -->
<script src="../../js/apiService.js"></script>
<script src="../../js/dataManager.js"></script>
<script src="../../js/userManager.js"></script>
<script src="../../js/accessTracker.js"></script>
<script src="../../js/gameTracker.js"></script>
<script src="../../js/gameDataLogger.js"></script>
<style>
/* 全局样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Comic Neue", cursive;
background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%);
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
/* 气球装饰 */
.balloon {
position: absolute;
width: 80px;
height: 100px;
background: radial-gradient(circle at 30% 30%, #ff9a9e, #fad0c4);
border-radius: 50%;
box-shadow: inset -10px -10px 10px rgba(0, 0, 0, 0.1);
animation: float 15s infinite ease-in-out;
z-index: -1;
}
.balloon::after {
content: "";
position: absolute;
bottom: -15px;
left: 50%;
width: 2px;
height: 30px;
background: #ff9a9e;
transform: translateX(-50%);
}
/* 鲜花装饰 */
.flower {
position: absolute;
width: 60px;
height: 60px;
background: radial-gradient(
circle at center,
#ffe66d 30%,
#ff9a9e 100%
);
border-radius: 50%;
animation: sway 8s infinite ease-in-out;
z-index: -1;
}
.flower::before {
content: "";
position: absolute;
bottom: -20px;
left: 50%;
width: 3px;
height: 40px;
background: #74b9ff;
transform: translateX(-50%);
}
@keyframes float {
0%,
100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-50px) rotate(5deg);
}
}
@keyframes sway {
0%,
100% {
transform: translateX(0) rotate(0deg);
}
50% {
transform: translateX(20px) rotate(10deg);
}
}
/* 主容器样式 */
.main-container {
width: 90%;
max-width: 1000px;
height: 90vh;
position: relative;
overflow: hidden;
background: rgba(255, 255, 255, 0.8);
border-radius: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
border: 8px solid #ffe66d;
transition: all 0.3s ease;
}
.main-container:hover {
transform: scale(1.02);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
}
/* 开始菜单样式 */
.start-menu {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, 0.9);
border-radius: 30px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
z-index: 10;
transition: all 0.5s ease;
}
.start-title {
font-size: 5rem;
color: #ff6b6b;
text-shadow: 5px 5px 0 #ffe66d;
margin-bottom: 50px;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%,
100% {
transform: translateY(0);
}
25% {
transform: translateY(-2px);
animation-timing-function: ease-in-out;
}
50% {
transform: translateY(0);
}
75% {
transform: translateY(2px);
animation-timing-function: ease-in-out;
}
}
.start-button {
width: 200px;
height: 200px;
border-radius: 50%;
background: linear-gradient(145deg, #ff9a9e, #ff6b6b);
border: 5px solid #ffe66d;
color: white;
font-size: 2.5rem;
cursor: pointer;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3),
inset 0 0 20px rgba(255, 255, 255, 0.5);
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
transition: all 0.3s;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.start-button:hover {
transform: scale(1.1);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4);
}
.start-button::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(
circle,
rgba(255, 255, 255, 0.8) 0%,
rgba(255, 255, 255, 0) 70%
);
transform: scale(0);
transition: transform 0.5s;
}
.start-button:active::before {
transform: scale(1);
}
/* 游戏界面样式 */
.game-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
flex-direction: column;
justify-content: flex-start;
align-items: center;
background: rgba(255, 255, 255, 0.9);
border-radius: 30px;
z-index: 5;
padding: 20px;
box-sizing: border-box;
}
.game-header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding: 0 10px;
}
.progress-container {
width: 60%;
height: 30px;
background-color: #f1f1f1;
border-radius: 15px;
overflow: hidden;
}
.progress-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #74b9ff, #0984e3);
border-radius: 15px;
transition: width 0.5s;
}
.back-button {
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(145deg, #ff7675, #d63031);
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.3s;
}
.back-button:hover {
transform: scale(1.1);
}
.game-content {
width: 100%;
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
padding: 10px 0;
}
.game-image {
width: 90%;
max-width: 500px;
height: auto;
max-height: 300px;
object-fit: contain;
margin: 20px 0;
border-radius: 20px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
}
.number-options {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 15px;
width: 100%;
max-width: 600px;
margin: 20px 0;
}
.number-btn {
width: 100px;
height: 100px;
border-radius: 50%;
color: white;
font-size: 3rem;
border: none;
cursor: pointer;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.number-btn[data-number="1"] {
background: linear-gradient(145deg, #74b9ff, #0984e3);
}
.number-btn[data-number="2"] {
background: linear-gradient(145deg, #ff7675, #d63031);
}
.number-btn[data-number="3"] {
background: linear-gradient(145deg, #55efc4, #00b894);
}
.number-btn[data-number="4"] {
background: linear-gradient(145deg, #a29bfe, #6c5ce7);
}
.number-btn[data-number="5"] {
background: linear-gradient(145deg, #ffeaa7, #fdcb6e);
}
.number-btn:hover {
transform: scale(1.1);
box-shadow: 0 15px 25px rgba(0, 0, 0, 0.3);
}
.number-btn::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 5px;
height: 5px;
background: rgba(255, 255, 255, 0.5);
opacity: 0;
border-radius: 100%;
transform: scale(1, 1) translate(-50%, -50%);
transform-origin: 50% 50%;
}
.number-btn:focus:not(:active)::after {
animation: ripple 1s ease-out;
}
@keyframes ripple {
0% {
transform: scale(0, 0);
opacity: 0.5;
}
100% {
transform: scale(20, 20);
opacity: 0;
}
}
.feedback {
height: 80px;
width: 80px;
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
font-size: 4rem;
opacity: 0;
transition: all 0.3s;
}
.correct {
color: #00b894;
animation: correct-feedback 0.5s;
}
.incorrect {
color: #d63031;
animation: incorrect-feedback 0.5s;
}
@keyframes correct-feedback {
0% {
transform: scale(0);
opacity: 0;
}
50% {
transform: scale(1.5);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
@keyframes incorrect-feedback {
0%,
100% {
transform: translateX(0);
}
20%,
60% {
transform: translateX(-10px);
}
40%,
80% {
transform: translateX(10px);
}
}
/* 胜利界面样式 */
.victory-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.8);
border-radius: 30px;
z-index: 20;
}
.victory-content {
text-align: center;
color: white;
}
.victory-icon {
font-size: 10rem;
margin-bottom: 30px;
color: #ffe66d;
text-shadow: 0 0 20px #ff9f43;
animation: victory-glow 2s infinite;
}
@keyframes victory-glow {
0%,
100% {
transform: scale(1);
text-shadow: 0 0 20px #ff9f43;
}
50% {
transform: scale(1.2);
text-shadow: 0 0 40px #ff9f43;
}
}
.victory-button {
width: 150px;
height: 150px;
border-radius: 50%;
background: linear-gradient(145deg, #00b894, #55efc4);
border: none;
color: white;
font-size: 2rem;
cursor: pointer;
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
margin-top: 50px;
transition: all 0.3s;
}
.victory-button:hover {
transform: scale(1.1);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
/* 粒子特效 */
.particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 30;
}
.particle {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ffe66d;
opacity: 0;
}
/* 音量开关按钮样式 */
.sound-toggle {
width: 80px;
height: 80px;
border-radius: 50%;
background: linear-gradient(145deg, #74b9ff, #0984e3);
border: 3px solid #ffe66d;
color: white;
font-size: 2.5rem;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s;
}
.sound-toggle:hover {
transform: scale(1.1);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
/* 响应式设计 */
@media (max-width: 768px) {
.start-title {
font-size: 3rem;
}
.start-button {
width: 150px;
height: 150px;
}
.game-image {
width: 90%;
height: auto;
max-height: 250px;
}
.number-btn {
width: 70px;
height: 70px;
font-size: 2rem;
}
.sound-toggle {
width: 60px;
height: 60px;
font-size: 2rem;
}
}
</style>
<script>
// 添加随机气球
function createBalloons() {
const colors = ["#ff9a9e", "#74b9ff", "#ffe66d", "#a29bfe", "#55efc4"];
for (let i = 0; i < 8; i++) {
const balloon = document.createElement("div");
balloon.className = "balloon";
balloon.style.left = Math.random() * 100 + "%";
balloon.style.top = Math.random() * 100 + "%";
balloon.style.width = Math.random() * 40 + 60 + "px";
balloon.style.height = Math.random() * 60 + 80 + "px";
balloon.style.background = `radial-gradient(circle at 30% 30%, ${
colors[i % colors.length]
}, ${colors[(i + 1) % colors.length]})`;
balloon.style.animationDuration = Math.random() * 10 + 10 + "s";
document.body.appendChild(balloon);
}
}
// 添加随机鲜花
function createFlowers() {
const colors = ["#ffe66d", "#ff9a9e", "#74b9ff", "#a29bfe", "#55efc4"];
for (let i = 0; i < 6; i++) {
const flower = document.createElement("div");
flower.className = "flower";
flower.style.left = Math.random() * 100 + "%";
flower.style.top = Math.random() * 100 + "%";
flower.style.width = Math.random() * 30 + 50 + "px";
flower.style.height = Math.random() * 30 + 50 + "px";
flower.style.background = `radial-gradient(circle at center, ${
colors[i % colors.length]
} 30%, ${colors[(i + 2) % colors.length]} 100%)`;
flower.style.animationDuration = Math.random() * 5 + 8 + "s";
document.body.appendChild(flower);
}
}
// 页面加载后创建装饰
window.onload = function () {
createBalloons();
createFlowers();
};
</script>
</head>
<body>
<audio src="" controls id="audioPlayer" style="display: none"></audio>
<audio
src="MP3/背景音1.mp3"
id="bgMusic"
loop
style="display: none"
></audio>
<div class="main-container">
<!-- 开始菜单 -->
<div class="start-menu">
<h1 class="start-title">数字乐园</h1>
<div
style="
display: flex;
justify-content: center;
gap: 20px;
width: 100%;
margin-top: 20px;
"
>
<button
class="start-button"
id="numberButton"
style="display: flex; flex-direction: column; align-items: center"
>
<span style="font-size: 3rem; margin-bottom: 10px">🔢</span>
<span style="font-size: 1.2rem">数字学习</span>
</button>
<button
class="start-button"
id="audioGameButton"
style="display: flex; flex-direction: column; align-items: center"
>
<span style="font-size: 3rem; margin-bottom: 10px">👂</span>
<span style="font-size: 1.2rem">听音识数</span>
</button>
<button
class="start-button"
id="pictureGameButton"
style="display: flex; flex-direction: column; align-items: center"
>
<span style="font-size: 3rem; margin-bottom: 10px">👀</span>
<span style="font-size: 1.2rem">看图识数</span>
</button>
</div>
<button class="sound-toggle" id="soundToggle" style="margin-top: 30px">
<span class="sound-icon">🔊</span>
</button>
</div>
<!-- 游戏界面 -->
<div class="game-screen" id="gameScreen">
<div class="game-header">
<button class="back-button" id="backButton"></button>
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
</div>
<div class="game-content">
<img
class="game-image"
id="gameImage"
src="img/1/1.png"
alt="数字图片"
/>
<div class="number-options">
<button class="number-btn" data-number="1">1</button>
<button class="number-btn" data-number="2">2</button>
<button class="number-btn" data-number="3">3</button>
<button class="number-btn" data-number="4">4</button>
<button class="number-btn" data-number="5">5</button>
</div>
<div class="feedback" id="feedback"></div>
</div>
</div>
<!-- 胜利界面 -->
<div class="victory-screen" id="victoryScreen">
<div class="victory-content">
<div class="victory-icon"></div>
<button class="victory-button" id="victoryButton"></button>
</div>
</div>
<!-- 粒子特效容器 -->
<div class="particles" id="particles"></div>
</div>
<script>
async function speak2(text, vcn = "x4_lingyouyou", speed = 50) {
try {
const params = new URLSearchParams();
params.append("text", text);
params.append("vcn", vcn);
params.append("speed", speed);
const response = await fetch(
"http://rgclass.iflysse.com:8200/text2audio",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: params,
}
);
if (!response.ok) throw new Error(`请求失败: ${response.status}`);
const audioPath = await response.text();
const audioUrl = `http://rgclass.iflysse.com:8200${audioPath.trim()}`;
const audioPlayer = document.querySelector("#audioPlayer");
audioPlayer.src = audioUrl;
setTimeout(() => {
audioPlayer.load();
audioPlayer.play();
}, 200);
} catch (error) {
console.error("请求出错:", error);
}
}
// 游戏数据
const questions = [
{ image: "img/1/1.png", answer: 1 },
{ image: "img/2/1.png", answer: 2 },
{ image: "img/3/1.png", answer: 3 },
{ image: "img/4/1.png", answer: 4 },
{ image: "img/5/1.png", answer: 5 },
{ image: "img/1/2.png", answer: 1 },
{ image: "img/2/2.png", answer: 2 },
{ image: "img/3/2.png", answer: 3 },
{ image: "img/4/2.png", answer: 4 },
{ image: "img/5/2.png", answer: 5 },
];
// 游戏模式
let gameMode = "picture"; // 'picture'或'audio'
// 游戏状态
let currentQuestion = 0;
let correctAnswers = 0;
const totalQuestions = 5; // 需要答对的题目数量
let gameStarted = false;
let timer; // 倒计时计时器
// DOM元素
const startMenu = document.querySelector(".start-menu");
const gameScreen = document.getElementById("gameScreen");
const victoryScreen = document.getElementById("victoryScreen");
const startButton = document.getElementById("startButton");
const backButton = document.getElementById("backButton");
const victoryButton = document.getElementById("victoryButton");
const gameImage = document.getElementById("gameImage");
const feedback = document.getElementById("feedback");
const progressBar = document.getElementById("progressBar");
const particlesContainer = document.getElementById("particles");
// 事件监听
document.addEventListener("DOMContentLoaded", function () {
console.log("DOM fully loaded");
// 确保按钮存在
const numberButton = document.getElementById("numberButton");
if (numberButton) {
numberButton.addEventListener("click", function () {
// 创建数字语音学习界面
const voiceScreen = document.createElement("div");
voiceScreen.className = "start-menu";
voiceScreen.style.position = "absolute";
voiceScreen.innerHTML = `
<h1 class="start-title">数字语音</h1>
<div class="number-options" style="margin-top: 30px;">
<button class="number-btn" data-number="1">1</button>
<button class="number-btn" data-number="2">2</button>
<button class="number-btn" data-number="3">3</button>
<button class="number-btn" data-number="4">4</button>
<button class="number-btn" data-number="5">5</button>
</div>
<button class="start-button" style="margin-top: 30px;" id="backToMain">返回</button>
`;
document.querySelector(".main-container").appendChild(voiceScreen);
// 数字按钮点击事件
voiceScreen.querySelectorAll(".number-btn").forEach((btn) => {
btn.addEventListener("click", function () {
const number = parseInt(this.dataset.number);
speak2(`这是数字${number}`);
});
});
// 返回按钮事件
voiceScreen
.querySelector("#backToMain")
.addEventListener("click", function () {
voiceScreen.remove();
});
});
}
const audioGameButton = document.getElementById("audioGameButton");
if (audioGameButton) {
audioGameButton.addEventListener("click", () => initGame("audio"));
}
const pictureGameButton = document.getElementById("pictureGameButton");
if (pictureGameButton) {
pictureGameButton.addEventListener("click", () =>
initGame("picture")
);
}
const voiceButton = document.getElementById("voiceButton");
if (voiceButton) {
voiceButton.addEventListener("click", function () {
// 创建数字语音学习界面
const voiceScreen = document.createElement("div");
voiceScreen.className = "start-menu";
voiceScreen.style.position = "absolute";
voiceScreen.innerHTML = `
<h1 class="start-title">数字语音</h1>
<div class="number-options" style="margin-top: 30px;">
<button class="number-btn" data-number="1">1</button>
<button class="number-btn" data-number="2">2</button>
<button class="number-btn" data-number="3">3</button>
<button class="number-btn" data-number="4">4</button>
<button class="number-btn" data-number="5">5</button>
</div>
<button class="start-button" style="margin-top: 30px;" id="backToMain">返回</button>
`;
document.querySelector(".main-container").appendChild(voiceScreen);
// 数字按钮点击事件
voiceScreen.querySelectorAll(".number-btn").forEach((btn) => {
btn.addEventListener("click", function () {
const number = parseInt(this.dataset.number);
speak2(`这是数字${number}`);
});
});
// 返回按钮事件
voiceScreen
.querySelector("#backToMain")
.addEventListener("click", function () {
voiceScreen.remove();
});
});
}
if (backButton) {
backButton.addEventListener("click", backToMenu);
backButton.disabled = false;
}
if (victoryButton) {
victoryButton.addEventListener("click", backToMenu);
victoryButton.disabled = false;
}
// 数字按钮事件监听
document.querySelectorAll(".number-btn").forEach((btn) => {
btn.addEventListener("click", function () {
if (!this.disabled) {
checkAnswer(parseInt(this.dataset.number));
}
});
});
// 初始隐藏游戏和胜利界面
gameScreen.style.display = "none";
victoryScreen.style.display = "none";
// 显示开始菜单
startMenu.style.display = "flex";
startMenu.style.opacity = "1";
startMenu.style.pointerEvents = "auto";
});
// 音效控制
const soundToggle = document.getElementById("soundToggle");
let isSoundOn = true;
soundToggle.addEventListener("click", function () {
isSoundOn = !isSoundOn;
const soundIcon = this.querySelector(".sound-icon");
soundIcon.textContent = isSoundOn ? "🔊" : "🔇";
// 控制所有音频元素
document.querySelectorAll("audio").forEach((audio) => {
audio.muted = !isSoundOn;
});
// 播放音效状态提示
if (isSoundOn) {
speak2("音效已开启");
}
// 添加动画效果
this.style.transform = "scale(1.2)";
setTimeout(() => {
this.style.transform = "scale(1)";
}, 200);
});
// 初始化游戏
function initGame(mode = "picture") {
gameMode = mode;
currentQuestion = 0;
correctAnswers = 0;
gameStarted = true;
progressBar.style.width = "0%";
// 开始游戏跟踪
if (window.gameTracker) {
window.gameTracker.startGame(3, {
// 识数小精灵游戏ID
gameType: "number_recognition",
mode: mode,
totalQuestions: totalQuestions,
});
}
// 根据模式播放不同的背景音乐
const bgMusic = document.getElementById("bgMusic");
bgMusic.volume = 0.3;
bgMusic.muted = !isSoundOn;
if (mode === "picture") {
bgMusic.src = "MP3/背景音1.mp3";
speak2("小朋友,请观察图片并选择对应的数字");
} else if (mode === "audio") {
bgMusic.src = "MP3/背景音2.mp3";
speak2("小朋友,请听声音并选择对应的数字");
} else {
bgMusic.src = "MP3/背景音3.mp3";
}
bgMusic.play().catch((e) => console.log("自动播放被阻止:", e));
// 随机排序问题
shuffleArray(questions);
// 停止所有按钮的晃动效果
const numberButtons = document.querySelectorAll(".number-btn");
const audioButtons = document.querySelectorAll(".audio-btn");
const pictureButtons = document.querySelectorAll(".picture-btn");
numberButtons.forEach((btn) => {
btn.style.animation = "none";
});
audioButtons.forEach((btn) => {
btn.style.animation = "none";
});
pictureButtons.forEach((btn) => {
btn.style.animation = "none";
});
// 加载第一个问题
loadQuestion(currentQuestion);
// 显示游戏界面
startMenu.style.opacity = "0";
startMenu.style.pointerEvents = "none";
setTimeout(() => {
startMenu.style.display = "none";
gameScreen.style.display = "flex";
}, 500);
}
if (gameMode === "picture") {
speak2("小朋友,请观察图片并选择对应的数字");
} else {
speak2("小朋友,请听声音并选择对应的数字");
}
// 加载问题
function loadQuestion(index) {
if (index >= questions.length) {
shuffleArray(questions);
currentQuestion = 0;
}
// 重置错误计数器
window.errorCount = 0;
if (gameMode === "picture") {
gameImage.src = questions[index].image;
gameImage.style.display = "block";
} else {
gameImage.style.display = "none";
const correctNumber = questions[currentQuestion].answer;
speak2(`请找出数字${correctNumber}`);
}
feedback.style.opacity = "0";
feedback.textContent = "";
// 恢复所有数字按钮状态
const numberButtons = document.querySelectorAll(".number-btn");
numberButtons.forEach((btn) => {
btn.disabled = false;
btn.style.opacity = "1";
btn.style.cursor = "pointer";
btn.style.boxShadow = "0 10px 20px rgba(0, 0, 0, 0.2)";
});
// 清除之前的倒计时
if (timer) clearTimeout(timer);
// 设置5秒倒计时
timer = setTimeout(() => {
const correctNumber = questions[currentQuestion].answer;
const correctBtn = document.querySelector(
`.number-btn[data-number="${correctNumber}"]`
);
if (correctBtn) {
correctBtn.style.boxShadow = "0 0 20px 10px rgba(0, 255, 0, 0.5)";
correctBtn.style.transition = "box-shadow 2s ease-in-out";
// 添加晃动动画
correctBtn.style.animation = "bounce 0.5s infinite";
// 播放语音提示
if (gameMode === "picture") {
speak2("小朋友,选择正确的数字吧");
} else {
speak2(`请找出数字${correctNumber}`);
}
}
}, 5000);
}
// 检查答案
function checkAnswer(selectedNumber) {
if (!gameStarted) return;
// 清除倒计时
if (timer) clearTimeout(timer);
// 错误计数
if (typeof window.errorCount === "undefined") {
window.errorCount = 0;
}
const correctNumber = questions[currentQuestion].answer;
const isCorrect = selectedNumber === correctNumber;
// 详细数据打印
console.log("🎯 识数小精灵游戏 - 用户选择记录");
console.log("📊 问题信息:", {
问题编号: currentQuestion + 1,
问题内容: questions[currentQuestion].question || "未知问题",
正确答案: correctNumber,
用户选择: selectedNumber,
是否正确: isCorrect ? "✅ 正确" : "❌ 错误",
错误次数: window.errorCount,
});
console.log("📈 游戏进度:", {
当前得分: correctAnswers,
总问题数: totalQuestions,
完成进度: `${((correctAnswers / totalQuestions) * 100).toFixed(1)}%`,
});
console.log("⏰ 时间信息:", {
选择时间: new Date().toLocaleString("zh-CN"),
游戏时长: window.gameTracker
? window.gameTracker.getCurrentPlayTime() + "秒"
: "未知",
});
// 记录游戏尝试
if (window.gameTracker) {
window.gameTracker.recordAttempt();
}
if (isCorrect) {
// 正确答案处理
speak2("你太棒啦");
feedback.textContent = "✓";
feedback.className = "feedback correct";
feedback.style.opacity = "1";
// 移除正确按钮的晃动效果
const correctBtn = document.querySelector(
`.number-btn[data-number="${correctNumber}"]`
);
if (correctBtn) correctBtn.style.animation = "none";
// 禁用所有数字按钮
document.querySelectorAll(".number-btn").forEach((btn) => {
btn.disabled = true;
btn.style.opacity = "0.5";
btn.style.cursor = "not-allowed";
});
correctAnswers++;
progressBar.style.width = `${
(correctAnswers / totalQuestions) * 100
}%`;
createParticles(); // 正确答案时显示特效
// 记录正确答案
if (window.gameTracker) {
window.gameTracker.recordCorrect(10, {
question: questions[currentQuestion].question || "未知问题",
selected: selectedNumber,
correct: correctNumber,
questionNumber: currentQuestion + 1,
totalQuestions: totalQuestions,
errorCount: window.errorCount,
});
}
// 检查是否胜利
if (correctAnswers >= totalQuestions) {
showVictory();
} else {
// 延迟加载下一题
setTimeout(() => {
particlesContainer.innerHTML = ""; // 清除特效
currentQuestion++;
loadQuestion(currentQuestion);
}, 4000); // 延长到4秒
}
} else {
// 错误答案处理
speak2("答错了我们再想一想");
feedback.textContent = "✗";
feedback.className = "feedback incorrect";
feedback.style.opacity = "1";
// 增加错误计数
window.errorCount++;
// 记录错误答案
if (window.gameTracker) {
window.gameTracker.recordIncorrect(0, {
question: questions[currentQuestion].question || "未知问题",
selected: selectedNumber,
correct: correctNumber,
questionNumber: currentQuestion + 1,
totalQuestions: totalQuestions,
errorCount: window.errorCount,
});
}
// 禁用错误数字按钮
const numberButtons = document.querySelectorAll(".number-btn");
numberButtons.forEach((btn) => {
if (parseInt(btn.textContent) === selectedNumber) {
btn.disabled = true;
btn.style.opacity = "0.5";
btn.style.cursor = "not-allowed";
}
});
// 清除之前的计时器
if (timer) clearTimeout(timer);
// 如果错误达到2次立即显示提示
if (window.errorCount >= 2) {
const correctNumber = questions[currentQuestion].answer;
const correctBtn = document.querySelector(
`.number-btn[data-number="${correctNumber}"]`
);
if (correctBtn) {
correctBtn.style.boxShadow = "0 0 20px 10px rgba(0, 255, 0, 0.5)";
correctBtn.style.transition = "box-shadow 2s ease-in-out";
correctBtn.style.animation = "bounce 0.5s infinite";
speak2("小朋友,正确的数字是" + correctNumber);
}
} else {
// 设置5秒后显示正确答案提示
timer = setTimeout(() => {
const correctNumber = questions[currentQuestion].answer;
const correctBtn = document.querySelector(
`.number-btn[data-number="${correctNumber}"]`
);
if (correctBtn) {
correctBtn.style.boxShadow =
"0 0 20px 10px rgba(0, 255, 0, 0.5)";
correctBtn.style.transition = "box-shadow 2s ease-in-out";
correctBtn.style.animation = "bounce 0.5s infinite";
speak2("小朋友,正确的数字是" + correctNumber);
}
}, 5000);
}
}
}
// 显示胜利界面
function showVictory() {
speak2("小朋友你通关了你太厉害了");
gameScreen.style.display = "none";
victoryScreen.style.display = "flex";
// 根据游戏模式播放不同的胜利音效
const victorySound = document.createElement("audio");
if (isSoundOn) {
if (gameMode === "picture") {
victorySound.src = "MP3/最终胜利2.mp3";
} else {
victorySound.src = "MP3/胜利1.mp3";
}
// 受音量开关控制
const soundToggle = document.getElementById("soundToggle");
victorySound.muted = soundToggle.dataset.state === "off";
victorySound.play();
}
createParticles();
gameStarted = false;
}
// 返回菜单
function backToMenu() {
gameScreen.style.display = "none";
victoryScreen.style.display = "none";
startMenu.style.display = "flex";
startMenu.style.opacity = "1";
startMenu.style.pointerEvents = "auto";
// 清除粒子效果
particlesContainer.innerHTML = "";
// 暂停背景音乐
document.getElementById("bgMusic").pause();
// 重置游戏状态
gameStarted = false;
currentQuestion = 0;
correctAnswers = 0;
progressBar.style.width = "0%";
// 停止所有按钮的晃动效果
const numberButtons = document.querySelectorAll(".number-btn");
const audioButtons = document.querySelectorAll(".audio-btn");
const pictureButtons = document.querySelectorAll(".picture-btn");
numberButtons.forEach((btn) => {
btn.style.animation = "none";
});
audioButtons.forEach((btn) => {
btn.style.animation = "none";
});
pictureButtons.forEach((btn) => {
btn.style.animation = "none";
});
}
setTimeout(() => {
startMenu.style.opacity = "1";
startMenu.style.pointerEvents = "auto";
}, 100);
gameStarted = false;
// 重新开始游戏
function restartGame() {
victoryScreen.style.display = "none";
initGame();
}
// 数组随机排序
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// 创建粒子特效
function createParticles() {
particlesContainer.innerHTML = "";
for (let i = 0; i < 50; i++) {
const particle = document.createElement("div");
particle.className = "particle";
// 随机位置
const x = Math.random() * 100;
const y = Math.random() * 100;
// 随机大小
const size = Math.random() * 10 + 5;
// 随机颜色
const hue = Math.random() * 60 + 30; // 黄色到橙色
particle.style.backgroundColor = `hsl(${hue}, 100%, 50%)`;
// 设置样式
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.left = `${x}%`;
particle.style.top = `${y}%`;
// 动画
const duration = Math.random() * 3 + 2;
const delay = Math.random() * 2;
particle.style.animation = `float ${duration}s ease-in-out ${delay}s infinite`;
particlesContainer.appendChild(particle);
}
}
// 添加粒子动画关键帧
const style = document.createElement("style");
style.type = "text/css";
style.innerHTML = `
@keyframes float {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(-100vh) rotate(360deg);
opacity: 0;
}
}
`;
document.head.appendChild(style);
</script>
</body>
</html>
<style>
/* 悬浮提示样式 */
.tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 15px;
border-radius: 10px;
font-size: 1.2rem;
max-width: 200px;
text-align: center;
z-index: 100;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
</style>
<div class="tooltip" id="tooltip">
// ... existing code ...
<script>
// 悬浮提示功能
const tooltips = {
numberButton: "学习数字1-5的发音和写法",
audioGameButton: "听数字发音并选择正确答案",
pictureGameButton: "观察图片并选择对应的数字",
};
function showTooltip(buttonId, text) {
const button = document.getElementById(buttonId);
const tooltip = document.getElementById("tooltip");
const rect = button.getBoundingClientRect();
tooltip.textContent = text;
tooltip.style.left = `${
rect.left + rect.width / 2 - tooltip.offsetWidth / 2
}px`;
tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`;
tooltip.style.opacity = "1";
if (isSoundOn) {
speak2(text);
}
}
function hideTooltip() {
document.getElementById("tooltip").style.opacity = "0";
}
// 为菜单按钮添加悬浮事件
document.getElementById("numberButton").onmouseover = () =>
showTooltip("numberButton", tooltips.numberButton);
document.getElementById("numberButton").onmouseout = hideTooltip;
document.getElementById("audioGameButton").onmouseover = () =>
showTooltip("audioGameButton", tooltips.audioGameButton);
document.getElementById("audioGameButton").onmouseout = hideTooltip;
document.getElementById("pictureGameButton").onmouseover = () =>
showTooltip("pictureGameButton", tooltips.pictureGameButton);
document.getElementById("pictureGameButton").onmouseout = hideTooltip;
</script>
</div>