Files
RGKT/rg-09112127/html/play/AI生活安全游戏.html
2025-10-10 19:44:14 +08:00

610 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AI生活安全游戏</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/virtualTeacher.js"></script>
<script src="../../js/gameVirtualTeacher.js"></script>
<script src="../../js/aiGameGenerator.js"></script>
<style>
:root {
--primary: #ff9aa2;
--secondary: #ffb7b2;
--accent: #ffdac1;
--correct: #b5ead7;
--wrong: #ff9aa2;
--button: #70a1ff;
--text: #5e5346;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Comic Sans MS", "Marker Felt", "微软雅黑", sans-serif;
background-color: #f9f7f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-image: radial-gradient(circle, #f5f5f5 10%, transparent 10%);
background-size: 30px 30px;
overflow: hidden;
}
.game-container {
width: 80%;
background-color: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
text-align: center;
position: relative;
overflow: hidden;
border: 5px solid #ffdac1;
}
h1 {
color: #ff6b6b;
margin-bottom: 30px;
font-size: 3rem;
text-shadow: 3px 3px 0 #ffdac1;
letter-spacing: 2px;
}
.question-area {
margin: 30px 0;
padding: 20px;
background-color: #f0f8ff;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.question {
font-size: 2.5rem;
margin: 20px 0;
color: #5e5346;
font-weight: bold;
line-height: 1.4;
}
.options {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin: 30px 0;
}
.option-btn {
padding: 20px;
border-radius: 15px;
background-color: var(--button);
color: white;
border: none;
font-size: 1.8rem;
font-weight: bold;
cursor: pointer;
box-shadow: 0 5px 0 #4a6baf;
transition: all 0.2s ease;
min-height: 80px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.option-btn:hover {
background-color: #5d8eff;
transform: scale(1.05);
}
.option-btn:active {
transform: translateY(5px);
box-shadow: 0 2px 0 #4a6baf;
}
.option-btn.correct {
background-color: var(--correct);
box-shadow: 0 5px 0 #8dd3c7;
}
.option-btn.wrong {
background-color: var(--wrong);
box-shadow: 0 5px 0 #e67e7e;
}
.score-area {
position: absolute;
top: 20px;
right: 20px;
background-color: #fff;
padding: 15px;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
font-size: 1.2rem;
font-weight: bold;
color: var(--text);
}
.progress-bar {
width: 100%;
height: 20px;
background-color: #e0e0e0;
border-radius: 10px;
margin: 20px 0;
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: var(--button);
transition: width 0.3s ease;
border-radius: 10px;
}
.message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
background-color: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
z-index: 100;
text-align: center;
max-width: 80%;
transition: all 0.3s ease;
border: 5px solid;
}
.message.show {
transform: translate(-50%, -50%) scale(1);
}
.message.correct {
border-color: #b5ead7;
background-color: #e8f8f3;
}
.message.wrong {
border-color: #ff9aa2;
background-color: #ffeef0;
}
.message h2 {
font-size: 3rem;
margin-bottom: 15px;
}
.message p {
font-size: 1.8rem;
margin-bottom: 20px;
line-height: 1.4;
}
.message-btn {
padding: 10px 20px;
border-radius: 50px;
border: none;
background-color: var(--button);
color: white;
font-size: 2rem;
cursor: pointer;
transition: all 0.2s ease;
}
.message-btn:hover {
background-color: #5d8eff;
transform: scale(1.05);
}
.confetti {
position: absolute;
width: 15px;
height: 15px;
background-color: var(--primary);
opacity: 0;
z-index: 90;
}
@keyframes confetti-fall {
0% {
transform: translateY(-100vh) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) rotate(360deg);
opacity: 0;
}
}
@media (max-width: 600px) {
.game-container {
width: 95%;
padding: 20px;
}
h1 {
font-size: 2rem;
}
.question {
font-size: 1.8rem;
}
.options {
grid-template-columns: 1fr;
}
.option-btn {
font-size: 1.5rem;
}
}
</style>
</head>
<body>
<div class="game-container">
<div class="score-area">
<div>得分: <span id="score">0</span></div>
<div>进度: <span id="progress">0</span>/<span id="total">5</span></div>
</div>
<h1>AI生活安全游戏</h1>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="question-area">
<div class="question" id="questionText">准备开始...</div>
<div class="options" id="optionsContainer">
<!-- 选项将通过JavaScript动态生成 -->
</div>
</div>
</div>
<div class="message" id="message">
<h2 id="messageTitle">标题</h2>
<p id="messageText">内容</p>
<button class="message-btn" id="messageBtn">继续</button>
</div>
<script>
// DOM元素
const questionText = document.getElementById("questionText");
const optionsContainer = document.getElementById("optionsContainer");
const message = document.getElementById("message");
const messageTitle = document.getElementById("messageTitle");
const messageText = document.getElementById("messageText");
const messageBtn = document.getElementById("messageBtn");
const scoreElement = document.getElementById("score");
const progressElement = document.getElementById("progress");
const totalElement = document.getElementById("total");
const progressFill = document.getElementById("progressFill");
// 游戏状态
let currentGame = null;
let currentQuestionIndex = 0;
let score = 0;
let correctCount = 0;
let gameStarted = false;
let gameId = "ai_life_safety_" + Date.now();
// 初始化AI游戏生成器
async function initAIGame() {
try {
if (!window.aiGameGenerator) {
throw new Error("AI游戏生成器未加载");
}
await window.aiGameGenerator.init();
console.log("✅ AI游戏生成器初始化成功");
// 生成生活安全游戏
currentGame = window.aiGameGenerator.generatePersonalizedGame(
"life",
"quiz",
5
);
if (currentGame && currentGame.questions.length > 0) {
// 筛选安全题目
const safetyQuestions = currentGame.questions.filter(
(q) =>
q.question.includes("安全") ||
q.question.includes("应该") ||
q.question.includes("过马路") ||
q.question.includes("陌生人") ||
q.question.includes("火灾") ||
q.question.includes("地震")
);
if (safetyQuestions.length > 0) {
currentGame.questions = safetyQuestions.slice(0, 5);
}
totalElement.textContent = currentGame.questions.length;
console.log("🎮 AI生活安全游戏生成成功:", currentGame);
return true;
} else {
throw new Error("无法生成游戏题目");
}
} catch (error) {
console.error("❌ AI游戏初始化失败:", error);
return false;
}
}
// 显示当前题目
function showCurrentQuestion() {
if (
!currentGame ||
currentQuestionIndex >= currentGame.questions.length
) {
endGame();
return;
}
const question = currentGame.questions[currentQuestionIndex];
questionText.textContent = question.question;
// 清空选项容器
optionsContainer.innerHTML = "";
// 创建选项按钮
question.options.forEach((option, index) => {
const button = document.createElement("button");
button.className = "option-btn";
button.textContent = option;
button.onclick = () => selectAnswer(index, question);
optionsContainer.appendChild(button);
});
// 更新进度
progressElement.textContent = currentQuestionIndex + 1;
progressFill.style.width = `${
((currentQuestionIndex + 1) / currentGame.questions.length) * 100
}%`;
}
// 选择答案
function selectAnswer(selectedIndex, question) {
if (message.classList.contains("show")) return;
const isCorrect = selectedIndex === question.correct;
const selectedButton = optionsContainer.children[selectedIndex];
const correctButton = optionsContainer.children[question.correct];
// 显示答案效果
selectedButton.classList.add(isCorrect ? "correct" : "wrong");
if (!isCorrect) {
correctButton.classList.add("correct");
}
// 虚拟老师反馈
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.stopAllSpeech();
setTimeout(() => {
if (isCorrect) {
window.gameVirtualTeacher.recordCorrect();
} else {
window.gameVirtualTeacher.recordIncorrect();
}
}, 300);
}
// 更新分数
if (isCorrect) {
correctCount++;
score += 10;
scoreElement.textContent = score;
}
// 记录游戏数据
if (gameStarted && window.gameTracker) {
if (isCorrect) {
window.gameTracker.recordCorrect(10, {
question: question.question,
selected: question.options[selectedIndex],
correct: question.options[question.correct],
questionNumber: currentQuestionIndex + 1,
});
} else {
window.gameTracker.recordIncorrect(0, {
question: question.question,
selected: question.options[selectedIndex],
correct: question.options[question.correct],
questionNumber: currentQuestionIndex + 1,
});
}
}
// 显示结果消息
const messageText = isCorrect
? `太棒了!${question.question} 的正确答案是 ${
question.options[question.correct]
}`
: `再想想!正确答案是 ${question.options[question.correct]}`;
showMessage(isCorrect, messageText);
if (isCorrect) {
createConfetti();
}
}
// 显示消息
function showMessage(isCorrect, text) {
message.className = "message " + (isCorrect ? "correct" : "wrong");
messageTitle.textContent = isCorrect ? "太棒了!" : "再试一次";
messageText.textContent = text;
message.classList.add("show");
}
// 创建彩色纸屑效果
function createConfetti() {
const colors = [
"#FF9AA2",
"#FFB7B2",
"#FFDAC1",
"#E2F0CB",
"#B5EAD7",
"#C7CEEA",
];
for (let i = 0; i < 50; i++) {
const confetti = document.createElement("div");
confetti.className = "confetti";
confetti.style.left = `${Math.random() * 100}%`;
confetti.style.backgroundColor =
colors[Math.floor(Math.random() * colors.length)];
confetti.style.width = `${Math.random() * 10 + 5}px`;
confetti.style.height = `${Math.random() * 10 + 5}px`;
confetti.style.animation = `confetti-fall ${
Math.random() * 2 + 2
}s linear forwards`;
confetti.style.animationDelay = `${Math.random() * 0.5}s`;
document.body.appendChild(confetti);
setTimeout(() => {
confetti.remove();
}, 3000);
}
}
// 下一题
function nextQuestion() {
message.classList.remove("show");
currentQuestionIndex++;
showCurrentQuestion();
}
// 结束游戏
function endGame() {
const successRate = (correctCount / currentGame.questions.length) * 100;
message.className = "message correct";
messageTitle.textContent = "游戏完成!";
messageText.textContent = `恭喜你完成了游戏!\n得分: ${score}\n正确率: ${successRate.toFixed(
1
)}%`;
message.classList.add("show");
// 虚拟老师游戏结束
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.gameEnd();
}
// 记录游戏结果
if (gameStarted && window.gameTracker) {
if (successRate >= 80) {
window.gameTracker.recordWin(score, {
totalQuestions: currentGame.questions.length,
correctCount: correctCount,
successRate: successRate,
});
} else {
window.gameTracker.recordLose(score, {
totalQuestions: currentGame.questions.length,
correctCount: correctCount,
successRate: successRate,
});
}
}
messageBtn.textContent = "重新开始";
messageBtn.onclick = restartGame;
}
// 重新开始游戏
function restartGame() {
currentQuestionIndex = 0;
score = 0;
correctCount = 0;
scoreElement.textContent = "0";
progressElement.textContent = "0";
progressFill.style.width = "0%";
message.classList.remove("show");
messageBtn.textContent = "继续";
messageBtn.onclick = nextQuestion;
showCurrentQuestion();
}
// 事件监听
messageBtn.addEventListener("click", nextQuestion);
// 页面加载完成后初始化
document.addEventListener("DOMContentLoaded", async function () {
// 初始化虚拟老师
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher
.init({
intro:
"欢迎来到AI生活安全游戏我会帮你学习生活中的安全知识准备好了吗",
})
.then(() => {
console.log("🦉 AI生活安全游戏虚拟老师初始化成功");
})
.catch((error) => {
console.error("❌ 虚拟老师初始化失败:", error);
});
}
// 初始化后端集成
Promise.all([window.userManager.init(), window.dataManager.init()])
.then(async () => {
console.log("后端集成初始化完成");
// 初始化AI游戏
const success = await initAIGame();
if (success) {
// 开始游戏跟踪
if (window.gameTracker) {
window.gameTracker.startGame(gameId, {
gameType: "ai_life_safety",
difficulty: "adaptive",
});
}
// 虚拟老师游戏开始
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.gameStart("AI生活安全游戏");
setTimeout(() => {
window.gameVirtualTeacher.speak(
"欢迎来到AI生活安全游戏我会帮你学习生活中的安全知识准备好了吗"
);
}, 1000);
}
gameStarted = true;
showCurrentQuestion();
} else {
showMessage(false, "游戏初始化失败,请刷新页面重试");
}
})
.catch((error) => {
console.error("后端集成初始化失败:", error);
showMessage(false, "系统初始化失败,请刷新页面重试");
});
});
</script>
</body>
</html>