初始提交
This commit is contained in:
671
rg-09112127/html/ai_game_generator.html
Normal file
671
rg-09112127/html/ai_game_generator.html
Normal file
@@ -0,0 +1,671 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user