Files
RGKT/rg-09112127/html/ai_game_generator.html

672 lines
21 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>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>