Files
RGKT/rg-09112127/html/ai_game_generator.html
2025-10-10 19:44:14 +08:00

672 lines
21 KiB
HTML
Raw Permalink 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>
<link rel="stylesheet" href="../css/indexDetail.css" />
<link rel="stylesheet" href="../css/userDisplay.css" />
<style>
.ai-generator-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.generator-header {
text-align: center;
margin-bottom: 30px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.generator-header h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.generator-header p {
font-size: 1.2em;
opacity: 0.9;
}
.generator-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 30px;
}
.generator-panel {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
border: 1px solid #e0e0e0;
}
.panel-title {
font-size: 1.5em;
font-weight: bold;
margin-bottom: 20px;
color: #333;
border-bottom: 2px solid #667eea;
padding-bottom: 10px;
}
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #555;
}
.form-select,
.form-input {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s;
}
.form-select:focus,
.form-input:focus {
outline: none;
border-color: #667eea;
}
.difficulty-slider {
width: 100%;
margin: 10px 0;
}
.difficulty-labels {
display: flex;
justify-content: space-between;
font-size: 0.9em;
color: #666;
}
.generate-btn {
width: 100%;
padding: 15px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 10px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.generate-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.generate-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.game-preview {
background: #f8f9fa;
border-radius: 10px;
padding: 20px;
margin-top: 20px;
min-height: 200px;
}
.question-item {
background: white;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
border-left: 4px solid #667eea;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.question-text {
font-weight: 600;
margin-bottom: 10px;
color: #333;
}
.question-options {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.option-item {
background: #e9ecef;
padding: 8px 12px;
border-radius: 5px;
text-align: center;
font-size: 0.9em;
}
.stats-panel {
grid-column: 1 / -1;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.stat-item {
text-align: center;
padding: 15px;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
backdrop-filter: blur(10px);
}
.stat-value {
font-size: 2em;
font-weight: bold;
margin-bottom: 5px;
}
.stat-label {
font-size: 0.9em;
opacity: 0.9;
}
.loading {
text-align: center;
padding: 40px;
color: #666;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.error-message {
background: #ffebee;
color: #c62828;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
border-left: 4px solid #c62828;
}
.success-message {
background: #e8f5e8;
color: #2e7d32;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
border-left: 4px solid #2e7d32;
}
@media (max-width: 768px) {
.generator-content {
grid-template-columns: 1fr;
}
.generator-header h1 {
font-size: 2em;
}
.question-options {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<!-- 导航条 -->
<div class="container-header">
<div class="container-header-logo">
<img src="../asset/logo.png" alt="logo" />
</div>
<nav class="container-header-nav">
<div data-url="indexHome">首页</div>
<div data-url="indexDetail">导航</div>
<div data-url="courseHome">课程</div>
<div data-url="student_analytics">数据分析</div>
<div class="active" data-url="ai_game_generator">AI游戏生成器</div>
</nav>
<div id="userDisplay" class="user-display"></div>
</div>
<!-- AI游戏生成器内容 -->
<div class="ai-generator-container">
<div class="generator-header">
<h1>🤖 AI智能游戏生成器</h1>
<p>
基于学习进度自动生成个性化游戏,智能调整难度,为每个学生定制专属学习体验
</p>
</div>
<div class="generator-content">
<!-- 游戏配置面板 -->
<div class="generator-panel">
<div class="panel-title">🎮 游戏配置</div>
<div class="form-group">
<label class="form-label">学科选择</label>
<select class="form-select" id="subjectSelect">
<option value="math">数学</option>
<option value="language">语文</option>
<option value="life">生活</option>
</select>
</div>
<div class="form-group">
<label class="form-label">游戏类型</label>
<select class="form-select" id="gameTypeSelect">
<option value="quiz">选择题游戏</option>
<option value="matching">配对游戏</option>
<option value="puzzle">拼图游戏</option>
<option value="memory">记忆游戏</option>
</select>
</div>
<div class="form-group">
<label class="form-label">题目数量</label>
<select class="form-select" id="questionCountSelect">
<option value="3">3题</option>
<option value="5" selected>5题</option>
<option value="8">8题</option>
<option value="10">10题</option>
</select>
</div>
<div class="form-group">
<label class="form-label"
>难度等级: <span id="difficultyValue">1</span></label
>
<input
type="range"
class="difficulty-slider"
id="difficultySlider"
min="1"
max="5"
value="1"
/>
<div class="difficulty-labels">
<span>简单</span>
<span>中等</span>
<span>困难</span>
</div>
</div>
<button
class="generate-btn"
id="generateBtn"
onclick="generateGame()"
>
🚀 生成个性化游戏
</button>
</div>
<!-- 游戏预览面板 -->
<div class="generator-panel">
<div class="panel-title">👀 游戏预览</div>
<div id="gamePreview" class="game-preview">
<div class="loading">
<div class="loading-spinner"></div>
<p>点击"生成个性化游戏"开始创建</p>
</div>
</div>
</div>
<!-- 统计面板 -->
<div class="generator-panel stats-panel">
<div class="panel-title">📊 学习统计</div>
<div class="stats-grid" id="statsGrid">
<div class="stat-item">
<div class="stat-value" id="currentDifficulty">1</div>
<div class="stat-label">当前难度</div>
</div>
<div class="stat-item">
<div class="stat-value" id="totalGames">0</div>
<div class="stat-label">总游戏数</div>
</div>
<div class="stat-item">
<div class="stat-value" id="successRate">0%</div>
<div class="stat-label">成功率</div>
</div>
<div class="stat-item">
<div class="stat-value" id="avgTime">0s</div>
<div class="stat-label">平均用时</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 引入脚本 -->
<script src="../js/jquery-3.7.1.min.js"></script>
<script src="../js/apiService.js"></script>
<script src="../js/dataManager.js"></script>
<script src="../js/userManager.js"></script>
<script src="../js/aiGameGenerator.js"></script>
<script>
let currentGame = null;
let isGenerating = false;
// 页面加载完成后初始化
document.addEventListener("DOMContentLoaded", async function () {
try {
// 初始化用户管理器
await window.userManager.init();
window.userManager.createUserDisplay();
// 初始化数据管理器
await window.dataManager.init();
// 初始化AI游戏生成器
await window.aiGameGenerator.init();
// 更新统计信息
updateStats();
// 设置难度滑块事件
document
.getElementById("difficultySlider")
.addEventListener("input", function () {
document.getElementById("difficultyValue").textContent =
this.value;
window.aiGameGenerator.currentDifficulty = parseInt(this.value);
});
// 设置导航事件
document
.querySelectorAll(".container-header-nav > div")
.forEach((item) => {
item.addEventListener("click", function () {
const url = this.getAttribute("data-url");
if (url !== "ai_game_generator") {
window.open(`./${url}.html`);
}
});
});
console.log("AI游戏生成器页面初始化完成");
} catch (error) {
console.error("初始化失败:", error);
showError("初始化失败,请刷新页面重试");
}
});
// 生成游戏
async function generateGame() {
if (isGenerating) return;
const generateBtn = document.getElementById("generateBtn");
const gamePreview = document.getElementById("gamePreview");
try {
isGenerating = true;
generateBtn.disabled = true;
generateBtn.textContent = "🔄 生成中...";
// 显示加载状态
gamePreview.innerHTML = `
<div class="loading">
<div class="loading-spinner"></div>
<p>AI正在分析学习数据生成个性化游戏...</p>
</div>
`;
// 获取当前用户
const currentUser = window.userManager.getCurrentUser();
if (!currentUser) {
throw new Error("请先登录");
}
// 获取配置
const subject = document.getElementById("subjectSelect").value;
const gameType = document.getElementById("gameTypeSelect").value;
const questionCount = parseInt(
document.getElementById("questionCountSelect").value
);
const difficulty = parseInt(
document.getElementById("difficultySlider").value
);
// 使用本地AI游戏生成器
if (!window.aiGameGenerator) {
throw new Error("AI游戏生成器未初始化");
}
// 设置难度
window.aiGameGenerator.currentDifficulty = difficulty;
// 生成完整游戏页面
const game = window.aiGameGenerator.generateGamePage(
subject,
gameType,
questionCount
);
if (game) {
currentGame = game;
// 显示游戏预览
displayGamePreview(currentGame);
showSuccess(
`成功生成${subject}学科的${gameType}游戏!游戏已嵌入当前页面。`
);
} else {
throw new Error("生成游戏失败");
}
} catch (error) {
console.error("生成游戏失败:", error);
showError("游戏生成失败,请重试");
gamePreview.innerHTML = `
<div class="loading">
<p>❌ 生成失败,请重试</p>
</div>
`;
} finally {
isGenerating = false;
generateBtn.disabled = false;
generateBtn.textContent = "🚀 生成个性化游戏";
}
}
// 显示游戏预览
function displayGamePreview(game) {
const gamePreview = document.getElementById("gamePreview");
let previewHTML = `
<div style="margin-bottom: 20px;">
<h3 style="color: #333; margin-bottom: 15px;">🎮 ${game.subject} - ${game.type} 游戏</h3>
<div style="display: flex; gap: 15px; margin-bottom: 15px; flex-wrap: wrap;">
<span style="background: #e3f2fd; color: #1976d2; padding: 5px 10px; border-radius: 15px; font-size: 0.9em;">
难度: ${game.difficulty}/5
</span>
<span style="background: #f3e5f5; color: #7b1fa2; padding: 5px 10px; border-radius: 15px; font-size: 0.9em;">
时间: ${game.timeLimit}
</span>
<span style="background: #e8f5e8; color: #388e3c; padding: 5px 10px; border-radius: 15px; font-size: 0.9em;">
提示: ${game.hints}
</span>
</div>
</div>
`;
// 显示题目预览
game.questions.forEach((question, index) => {
previewHTML += `
<div class="question-item">
<div class="question-text">第${index + 1}题: ${
question.question
}</div>
<div class="question-options">
${question.options
.map(
(option) =>
`<div class="option-item">${option}</div>`
)
.join("")}
</div>
</div>
`;
});
// 添加开始游戏按钮
previewHTML += `
<div style="text-align: center; margin-top: 20px;">
<button onclick="startGame()" style="
background: linear-gradient(135deg, #4caf50 0%, #45a049 100%);
color: white;
border: none;
padding: 12px 30px;
border-radius: 25px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s;
" onmouseover="this.style.transform='translateY(-2px)'" onmouseout="this.style.transform='translateY(0)'">
🎯 开始游戏
</button>
</div>
`;
gamePreview.innerHTML = previewHTML;
}
// 开始游戏
function startGame() {
if (!currentGame) {
showError("请先生成游戏");
return;
}
// 这里可以跳转到游戏页面或打开游戏窗口
showSuccess("游戏即将开始!");
console.log("开始游戏:", currentGame);
// 可以在这里集成到现有的游戏系统
// 例如window.open(`./play/game.html?gameId=${currentGame.id}`);
}
// 更新统计信息
async function updateStats() {
try {
const currentUser = window.userManager.getCurrentUser();
if (!currentUser) {
// 使用默认统计
document.getElementById("currentDifficulty").textContent = "1";
document.getElementById("totalGames").textContent = "0";
document.getElementById("successRate").textContent = "0%";
document.getElementById("avgTime").textContent = "0s";
return;
}
// 调用后端API获取统计
const response = await window.apiService.getStudentGameStats(
currentUser.id
);
if (response.success) {
const stats = response.data;
document.getElementById("currentDifficulty").textContent =
stats.currentLevel || 1;
document.getElementById("totalGames").textContent =
stats.totalGames || 0;
document.getElementById("successRate").textContent =
Math.round((stats.successRate || 0) * 100) + "%";
document.getElementById("avgTime").textContent =
Math.round(stats.avgTime || 0) + "s";
} else {
// 使用本地统计
const localStats = window.aiGameGenerator.getGameStats();
document.getElementById("currentDifficulty").textContent =
localStats.currentDifficulty;
document.getElementById("totalGames").textContent =
localStats.totalGames;
document.getElementById("successRate").textContent =
localStats.averageSuccessRate
? Math.round(localStats.averageSuccessRate * 100) + "%"
: "0%";
const avgTime =
localStats.performanceHistory.length > 0
? Math.round(
localStats.performanceHistory.reduce(
(sum, p) => sum + p.avgTimePerQuestion,
0
) / localStats.performanceHistory.length
)
: 0;
document.getElementById("avgTime").textContent = avgTime + "s";
}
} catch (error) {
console.error("获取统计信息失败:", error);
// 使用默认值
document.getElementById("currentDifficulty").textContent = "1";
document.getElementById("totalGames").textContent = "0";
document.getElementById("successRate").textContent = "0%";
document.getElementById("avgTime").textContent = "0s";
}
}
// 显示成功消息
function showSuccess(message) {
const gamePreview = document.getElementById("gamePreview");
const successDiv = document.createElement("div");
successDiv.className = "success-message";
successDiv.textContent = message;
gamePreview.insertBefore(successDiv, gamePreview.firstChild);
setTimeout(() => {
successDiv.remove();
}, 3000);
}
// 显示错误消息
function showError(message) {
const gamePreview = document.getElementById("gamePreview");
const errorDiv = document.createElement("div");
errorDiv.className = "error-message";
errorDiv.textContent = message;
gamePreview.insertBefore(errorDiv, gamePreview.firstChild);
setTimeout(() => {
errorDiv.remove();
}, 5000);
}
</script>
</body>
</html>