/** * AI讲故事主要功能类 * 提供故事库管理、阅读体验、AI语音交互等功能 */ class AIStorytelling { constructor() { this.stories = []; this.currentStory = null; this.currentSection = 0; this.isSpeaking = false; this.isVoiceEnabled = true; this.init(); } async init() { await this.loadStories(); this.initEventListeners(); this.renderStoryGrid(); this.initAdvancedFeatures(); if (window.virtualTeacher) { await window.virtualTeacher.init(); } console.log('🎭 AI讲故事系统初始化完成'); this.showWelcomeMessage(); this.updateStatsDisplay(); } initAdvancedFeatures() { // 初始化搜索功能 this.searchDelay = null; // 初始化排序功能 this.currentSort = 'default'; // 初始化收藏功能 this.favorites = JSON.parse(localStorage.getItem('storyFavorites') || '[]'); // 初始化语速控制 this.desiredRate = 0.8; // 初始化自动播放 this.autoPlay = false; // 初始化进度追踪 this.readingProgress = {}; // 初始化剧情选择系统 this.currentChoices = []; this.choicesHistory = []; this.branchingActive = false; this.waitingForChoice = false; } async loadStories() { try { const response = await fetch('../data/storyBank.json'); const data = await response.json(); this.stories = data.stories; console.log('📚 故事数据加载成功:', this.stories.length, '个故事'); // 调试:检查第一个故事的选择项 if (this.stories.length > 0) { const firstStory = this.stories[0]; console.log('🔍 第一个故事:', firstStory.title); console.log('🔍 第一个故事的选择项:', firstStory.content?.beginning?.choices); } } catch (error) { console.error('❌ 加载故事数据失败:', error); this.stories = this.getDefaultStories(); } } getDefaultStories() { return [{ id: "story_default", title: "欢迎来到故事世界", category: "欢迎故事", difficulty: 1, cover: "asset/logo.png", description: "这是一个欢迎故事,帮助您熟悉AI讲故事功能", timeEstimate: "2-3分钟", ageRange: "3-8岁", content: { beginning: { text: "欢迎来到AI讲故事的神奇世界!在这里,每一页都是一个新奇的冒险,每一个故事都充满智慧与乐趣。", image: "asset/logo.png" }, middle: { text: "AI老师会用温柔的声音为您朗读故事,就像真正的老师在身边一样。让我们一起来享受这个美好的故事时光吧!", image: "asset/maoz.png" }, ending: { text: "希望您喜欢这个AI讲故事世界!现在可以选择您感兴趣的故事,开始精彩的阅读之旅吧!", image: "asset/sping.png" } } }]; } initEventListeners() { document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', (e) => { this.filterStories(e.target.dataset.category); document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); e.target.classList.add('active'); }); }); document.getElementById('closeReader').addEventListener('click', () => { this.closeReader(); }); document.getElementById('prevSection').addEventListener('click', () => { this.previousSection(); }); document.getElementById('nextSection').addEventListener('click', () => { this.nextSection(); }); document.getElementById('readCurrentSection').addEventListener('click', () => { this.readCurrentSection(); }); document.getElementById('playPauseBtn').addEventListener('click', () => { this.togglePlayPause(); }); document.getElementById('stopBtn').addEventListener('click', () => { this.stopSpeaking(); }); // 语音控制面板切换按钮 document.getElementById('voiceToggleBtn').addEventListener('click', () => { this.toggleVoicePanel(); }); // 语音控制面板关闭按钮 document.getElementById('voiceCloseBtn').addEventListener('click', () => { this.hideVoicePanel(); }); // 语音开关功能(在语音控制面板内) document.getElementById('voiceOnOffBtn').addEventListener('click', () => { this.toggleVoice(); }); // 新增事件监听器 document.getElementById('speedControl')?.addEventListener('click', () => { this.openSpeedPanel(); }); document.getElementById('autoPlayBtn')?.addEventListener('click', () => { this.toggleAutoPlay(); }); document.getElementById('bookmarkBtn')?.addEventListener('click', () => { this.toggleFavorite(this.currentStory?.id); }); document.getElementById('shareBtn')?.addEventListener('click', () => { this.shareStory(); }); document.getElementById('sortBy')?.addEventListener('change', (e) => { this.sortStories(e.target.value); }); document.addEventListener('keydown', (e) => { if (document.getElementById('storyReader').classList.contains('active')) { switch (e.key) { case 'Escape': this.closeReader(); break; case 'ArrowLeft': this.previousSection(); break; case 'ArrowRight': this.nextSection(); break; case ' ': e.preventDefault(); this.readCurrentSection(); break; case 'a': case 'A': e.preventDefault(); this.toggleAutoPlay(); break; case 'b': case 'B': e.preventDefault(); this.toggleFavorite(this.currentStory?.id); break; } } }); document.getElementById('storyReader').addEventListener('click', (e) => { if (e.target.id === 'storyReader') { this.closeReader(); } }); // 语速面板事件监听 const speedSlider = document.getElementById('speedSlider'); const speedCloseBtn = document.getElementById('closeSpeedPanel'); const speedPresets = document.querySelectorAll('.speed-preset'); speedSlider?.addEventListener('input', (e) => { this.desiredRate = parseFloat(e.target.value); document.getElementById('speedValue').textContent = `${this.desiredRate.toFixed(1)}x`; this.updateVoiceSettings(); }); speedCloseBtn?.addEventListener('click', () => { this.closeSpeedPanel(); }); speedPresets.forEach(preset => { preset.addEventListener('click', (e) => { const speed = e.target.dataset.speed; this.desiredRate = parseFloat(speed); speedSlider.value = speed; document.getElementById('speedValue').textContent = `${speed}x`; this.updateVoiceSettings(); }); }); // 继续从分支剧情按钮 document.getElementById('continueFromBranch')?.addEventListener('click', () => { this.continueFromBranch(); }); } showWelcomeMessage() { setTimeout(() => { if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak("欢迎来到AI故事世界!这里有精彩的故事等着你,选择一个你喜欢的故事开始吧!", { rate: 0.8, pitch: 1.0 }); } }, 2000); } filterStories(category) { const filteredStories = category === 'all' ? this.stories : this.stories.filter(story => story.category === category); this.renderStoryGrid(filteredStories); if (window.virtualTeacher && this.isVoiceEnabled) { const categoryText = category === 'all' ? '所有故事' : category; window.virtualTeacher.speak(`现在显示${categoryText},共找到${filteredStories.length}个故事`); } } renderStoryGrid(storiesToRender = this.stories) { const grid = document.getElementById('storyGrid'); if (storiesToRender.length === 0) { grid.innerHTML = `

暂无故事

该分类下暂时没有故事,请选择其他分类。

`; return; } grid.innerHTML = '
正在加载故事...'; setTimeout(() => { grid.innerHTML = storiesToRender.map(story => `
${story.title}

${story.title}

${story.description}

`).join(''); }, 500); } generateDifficultyStars(difficulty) { return new Array(difficulty).fill('').map(() => '').join(''); } openReader(storyId) { console.log('🔍 openReader被调用,storyId:', storyId); console.log('📚 当前故事数组:', this.stories?.length || '未定义'); this.currentStory = this.stories.find(story => story.id === storyId); if (!this.currentStory) { console.error('❌ 找不到指定故事:', storyId); console.log('💾 可用故事列表:', this.stories?.map(s => ({ id: s.id, title: s.title })) || 'stories为undefined'); return; } console.log('✅ 找到故事:', this.currentStory.title); this.currentSection = 0; document.getElementById('readerTitle').textContent = this.currentStory.title; // 初始化进度到第1段 this.updateReadingProgress(this.currentStory.id, this.currentSection); this.renderStoryContent(); const reader = document.getElementById('storyReader'); reader.classList.add('active'); document.body.style.overflow = 'hidden'; if (window.virtualTeacher && this.isVoiceEnabled) { setTimeout(() => { window.virtualTeacher.speak(`欢迎来到《${this.currentStory.title}》的故事世界!`, { rate: 0.8, pitch: 1.1 }); }, 300); } console.log('📖 打开故事:', this.currentStory.title); } closeReader() { const reader = document.getElementById('storyReader'); reader.classList.remove('active'); document.body.style.overflow = ''; if (this.isSpeaking) { this.stopSpeaking(); } if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak('故事时间结束了,期待下次再见!', { rate: 0.8, pitch: 1.0 }); } console.log('📚 故事阅读器已关闭'); } renderStoryContent() { const content = document.getElementById('storyContent'); const sections = ['beginning', 'middle', 'ending']; const currentSectionData = this.currentStory.content[sections[this.currentSection]]; console.log('🔍 当前段落数据:', currentSectionData); console.log('🔍 是否有选择项:', currentSectionData.choices); console.log('🔍 选择项数量:', currentSectionData.choices?.length || 0); // 清除之前的定时器 if (this.branchingTimeout) { clearTimeout(this.branchingTimeout); this.branchingTimeout = null; } // 清除之前的选择和分支内容 const storyChoices = document.getElementById('storyChoices'); const branchingContent = document.getElementById('branchingContent'); const branchNarrative = document.getElementById('branchNarrative'); const choicesContainer = document.getElementById('choicesContainer'); const choiceFeedback = document.getElementById('choiceFeedback'); console.log('🔍 DOM元素检查:', { storyChoices: !!storyChoices, branchingContent: !!branchingContent, branchNarrative: !!branchNarrative, choicesContainer: !!choicesContainer, choiceFeedback: !!choiceFeedback }); if (storyChoices) storyChoices.style.display = 'none'; if (branchingContent) branchingContent.style.display = 'none'; if (branchNarrative) branchNarrative.innerHTML = ''; if (choicesContainer) choicesContainer.innerHTML = ''; if (choiceFeedback) choiceFeedback.innerHTML = ''; // 只更新故事内容部分,不覆盖选择界面 const storySection = document.createElement('div'); storySection.className = 'story-section'; storySection.innerHTML = `

📖 故事 ${this.getCurrentSectionTitle()}

${currentSectionData.image ? ` 故事插图 ` : ''}

${currentSectionData.text}

${this.currentSection + 1} / ${sections.length}
`; // 清除之前的故事内容,但保留选择界面 const existingStorySection = content.querySelector('.story-section'); if (existingStorySection) { content.removeChild(existingStorySection); } content.insertBefore(storySection, content.firstChild); // 渲染内容后刷新进度显示 this.updateReadingProgress(this.currentStory.id, this.currentSection); // 检查是否有选择项 - 始终显示选择界面,不管是否朗读 if (currentSectionData.choices && currentSectionData.choices.length > 0) { console.log('✅ 发现选择项,准备显示选择界面'); // 立即显示选择,让用户可以随时选择 setTimeout(() => { this.showStoryChoices(currentSectionData.choices); }, 500); } // 无论是否有选择项,都开始朗读(如果有语音功能) if (this.isVoiceEnabled) { setTimeout(() => { this.readCurrentSection(); }, 800); } } getCurrentSectionTitle() { const titles = ['开始', '中间', '结尾']; return titles[this.currentSection] || '段落'; } previousSection() { if (this.currentSection > 0) { this.currentSection--; // 更新进度 if (this.currentStory) { this.updateReadingProgress(this.currentStory.id, this.currentSection); } this.renderStoryContent(); if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak(`现在来到了故事的${this.getCurrentSectionTitle()}部分`); } } } nextSection() { const sections = ['beginning', 'middle', 'ending']; if (this.currentSection < sections.length - 1) { this.currentSection++; // 更新进度 if (this.currentStory) { this.updateReadingProgress(this.currentStory.id, this.currentSection); } this.renderStoryContent(); if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak(`现在来到了故事的${this.getCurrentSectionTitle()}部分`); } } else { this.showStoryEnding(); } } readCurrentSection() { if (!this.currentStory) return; const sections = ['beginning', 'middle', 'ending']; const currentSectionData = this.currentStory.content[sections[this.currentSection]]; if (window.virtualTeacher) { this.isSpeaking = true; const voiceBtn = document.getElementById('readCurrentSection'); voiceBtn.classList.add('speaking'); window.virtualTeacher.speak(currentSectionData.text, { rate: 0.8, pitch: 1.1, onend: () => { this.isSpeaking = false; voiceBtn.classList.remove('speaking'); } }); } } showStoryEnding() { const content = document.getElementById('storyContent'); content.innerHTML = `

🎉 故事结束了!

故事结束

恭喜你完成了《${this.currentStory.title}》的阅读!

${this.currentStory.description ? `

${this.currentStory.description}

` : ''}
`; // 结束时设置进度为 3/3 const sections = ['beginning', 'middle', 'ending']; this.updateReadingProgress(this.currentStory?.id || '', sections.length - 1); if (window.virtualTeacher && this.isVoiceEnabled) { setTimeout(() => { window.virtualTeacher.speak(`恭喜你完成了《${this.currentStory.title}》的阅读!希望你喜欢这个故事!`); }, 1000); } } restartStory() { this.currentSection = 0; this.renderStoryContent(); // 重启时重置进度为 1/3 if (this.currentStory) { this.updateReadingProgress(this.currentStory.id, this.currentSection); } if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak('让我们重新开始这个故事吧!'); } } showStoryInfo(storyId) { const story = this.stories.find(s => s.id === storyId); if (!story) return; // 填充对话框内容 const modal = document.getElementById('storyDetailModal'); const detailTitle = document.getElementById('detailTitle'); const detailImage = document.getElementById('detailImage'); const detailCategory = document.getElementById('detailCategory'); const detailCategoryIcon = document.getElementById('detailCategoryIcon'); const detailDifficulty = document.getElementById('detailDifficulty'); const detailDuration = document.getElementById('detailDuration'); const detailAge = document.getElementById('detailAge'); const detailDescription = document.getElementById('detailDescription'); const detailStart = document.getElementById('detailStart'); const detailFavorite = document.getElementById('detailFavorite'); const detailShare = document.getElementById('detailShare'); if (!modal) return; detailTitle.textContent = story.title; detailImage.src = `../${story.cover}`; detailCategory.textContent = story.category; // 设置类别图标 const categoryIconMap = { '生活故事': '../asset/icon-shenghuo.png', '经典故事': '../asset/icon-经典.png', '数学故事': '../asset/icon-xyz.png', '梦想故事': '../asset/icon-mengxiang1.png', '成长故事': '../asset/icon-chengzhang2.png' }; detailCategoryIcon.src = categoryIconMap[story.category] || '../asset/icon-shenghuo.png'; detailCategoryIcon.alt = story.category; detailDifficulty.textContent = '⭐'.repeat(story.difficulty || 1); detailDuration.textContent = story.timeEstimate || '约3分钟'; detailAge.textContent = story.ageRange || '3-8岁'; detailDescription.textContent = story.description || ''; // 绑定按钮动作 detailStart.onclick = () => { modal.style.display = 'none'; this.openReader(story.id); }; detailFavorite.onclick = () => this.toggleFavorite(story.id); detailShare.onclick = () => this.shareStory(); // 打开对话框 modal.style.display = 'block'; // 关闭事件(遮罩与关闭按钮) const closeBtn = document.getElementById('closeDetail'); const backdrop = document.getElementById('detailBackdrop'); const close = () => { modal.style.display = 'none'; }; closeBtn && (closeBtn.onclick = close); backdrop && (backdrop.onclick = close); } togglePlayPause() { const btn = document.getElementById('playPauseBtn'); const icon = btn.querySelector('i'); if (this.isSpeaking) { this.stopSpeaking(); icon.className = 'fa fa-play'; } else { this.readCurrentSection(); icon.className = 'fa fa-pause'; } } stopSpeaking() { if (window.virtualTeacher) { window.virtualTeacher.stopAllSpeech(); } this.isSpeaking = false; document.querySelectorAll('.speaking').forEach(el => el.classList.remove('speaking')); const playBtn = document.getElementById('playPauseBtn'); const icon = playBtn.querySelector('i'); icon.className = 'fa fa-play'; } toggleVoice() { this.isVoiceEnabled = !this.isVoiceEnabled; const btn = document.getElementById('voiceOnOffBtn'); const icon = btn.querySelector('i'); if (this.isVoiceEnabled) { icon.className = 'fa fa-volume-up'; btn.title = '关闭语音'; voiceBroadcast('语音功能已开启'); document.getElementById('voiceStatus').textContent = '语音已开启'; document.getElementById('voiceStatus').style.color = '#3b82f6'; } else { icon.className = 'fa fa-volume-off'; btn.title = '开启语音'; voiceBroadcast('语音功能已关闭'); this.stopSpeaking(); document.getElementById('voiceStatus').textContent = '语音已关闭'; document.getElementById('voiceStatus').style.color = '#94a3b8'; } } // 切换语音控制面板显示/隐藏 toggleVoicePanel() { const voiceControls = document.getElementById('voiceControls'); const toggleBtn = document.getElementById('voiceToggleBtn'); if (voiceControls.style.display === 'none' || voiceControls.style.display === '') { this.showVoicePanel(); } else { this.hideVoicePanel(); } } // 显示语音控制面板 showVoicePanel() { const voiceControls = document.getElementById('voiceControls'); const toggleBtn = document.getElementById('voiceToggleBtn'); voiceControls.style.display = 'block'; toggleBtn.style.display = 'none'; // 添加显示动画 setTimeout(() => { voiceControls.style.opacity = '1'; voiceControls.style.transform = 'translateY(0)'; }, 10); } // 隐藏语音控制面板 hideVoicePanel() { const voiceControls = document.getElementById('voiceControls'); const toggleBtn = document.getElementById('voiceToggleBtn'); voiceControls.style.opacity = '0'; voiceControls.style.transform = 'translateY(20px)'; setTimeout(() => { voiceControls.style.display = 'none'; toggleBtn.style.display = 'block'; }, 300); } // 新增功能方法 updateStatsDisplay() { const totalStories = this.stories.length; const totalDuration = this.stories.reduce((sum, story) => { const duration = parseInt(story.timeEstimate?.match(/\d+/)?.[0] || '3'); return sum + duration; }, 0); document.getElementById('totalStories').textContent = totalStories; document.getElementById('totalDuration').textContent = `${totalDuration}分钟`; } openSpeedPanel() { const panel = document.getElementById('speedPanel'); if (panel) { panel.classList.add('active'); document.getElementById('speedSlider').value = this.desiredRate; document.getElementById('speedValue').textContent = `${this.desiredRate.toFixed(1)}x`; } } closeSpeedPanel() { const panel = document.getElementById('speedPanel'); if (panel) { panel.classList.remove('active'); } } updateVoiceSettings() { // 更新语音设置,将应用到后续的朗读中 console.log('语速已更新为:', this.desiredRate); } toggleAutoPlay() { this.autoPlay = !this.autoPlay; const btn = document.getElementById('autoPlayBtn'); const icon = btn.querySelector('i'); if (this.autoPlay) { icon.className = 'fa fa-pause-circle'; btn.querySelector('.btn-text').textContent = '关闭自动'; btn.style.background = 'linear-gradient(135deg, #ef4444, #dc2626)'; if (this.isVoiceEnabled && window.virtualTeacher) { window.virtualTeacher.speak('自动播放已开启,我将自动为您朗读每个段落'); } } else { icon.className = 'fa fa-play-circle'; btn.querySelector('.btn-text').textContent = '自动播放'; btn.style.background = 'linear-gradient(135deg, #10b981, #059669)'; if (window.virtualTeacher) { window.virtualTeacher.stopAllSpeech(); } } } toggleFavorite(storyId) { if (!storyId) return; const index = this.favorites.indexOf(storyId); const btn = document.getElementById('bookmarkBtn'); const icon = btn.querySelector('i'); if (index > -1) { this.favorites.splice(index, 1); icon.className = 'fa fa-bookmark-o'; btn.style.color = '#ffffff'; if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak('已从收藏夹中移除'); } } else { this.favorites.push(storyId); icon.className = 'fa fa-bookmark'; btn.style.color = '#fbbf24'; if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak('已添加到收藏夹'); } } localStorage.setItem('storyFavorites', JSON.stringify(this.favorites)); } shareStory() { if (!this.currentStory) return; const storyInfo = { title: this.currentStory.title, description: this.currentStory.description, category: this.currentStory.category, url: window.location.href }; if (navigator.share) { navigator.share({ title: `${storyInfo.title} - AI讲故事`, text: storyInfo.description, url: storyInfo.url }); } else { // 复制到剪贴板 const shareText = `🌟 推荐一个AI故事:《${storyInfo.title}》\n\n${storyInfo.description}\n\n🔗 ${storyInfo.url}`; navigator.clipboard.writeText(shareText).then(() => { if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak('故事链接已复制到剪贴板'); } }); } } sortStories(sortType) { this.currentSort = sortType; let sortedStories = [...this.stories]; switch (sortType) { case 'difficulty': sortedStories.sort((a, b) => a.difficulty - b.difficulty); break; case 'duration': sortedStories.sort((a, b) => { const durationA = parseInt(a.timeEstimate?.match(/\d+/)?.[0] || '3'); const durationB = parseInt(b.timeEstimate?.match(/\d+/)?.[0] || '3'); return durationA - durationB; }); break; case 'popularity': // 基于收藏数量或人气排序(这里简化为随机) sortedStories.sort(() => Math.random() - 0.5); break; default: // 默认排序 break; } this.renderStoryGrid(sortedStories); if (window.virtualTeacher && this.isVoiceEnabled) { const sortText = { 'default': '默认顺序', 'difficulty': '按难度排序', 'duration': '按时长排序', 'popularity': '按受欢迎度排序' }; window.virtualTeacher.speak(`故事已按${sortText[sortType]}排列`); } } searchStories(query) { if (!query.trim()) { this.renderStoryGrid(); return; } const filteredStories = this.stories.filter(story => { const searchText = `${story.title} ${story.description} ${story.category}`.toLowerCase(); return searchText.includes(query.toLowerCase()); }); this.renderStoryGrid(filteredStories); if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak(`搜索到${filteredStories.length}个相关故事`); } } updateReadingProgress(storyId, sectionIndex) { this.readingProgress[storyId] = sectionIndex; localStorage.setItem('readingProgress', JSON.stringify(this.readingProgress)); // 更新进度条 const sections = ['beginning', 'middle', 'ending']; const progress = ((sectionIndex + 1) / sections.length) * 100; document.getElementById('progressFill').style.width = `${progress}%`; document.getElementById('progressText').textContent = `${sectionIndex + 1}/${sections.length}`; } // 剧情选择系统方法 showStoryChoices(choices) { console.log('🎭 showStoryChoices被调用,选择项:', choices); this.waitingForChoice = true; this.currentChoices = choices; // 显示选择界面 const choicesContainer = document.getElementById('choicesContainer'); const choicesElement = document.getElementById('storyChoices'); console.log('🔍 选择界面元素检查:', { choicesContainer: !!choicesContainer, choicesElement: !!choicesElement }); if (choicesContainer) { const choicesHTML = choices.map((choice, index) => ` `).join(''); console.log('🔍 生成的选择按钮HTML:', choicesHTML); choicesContainer.innerHTML = choicesHTML; } if (choicesElement) { choicesElement.style.display = 'block'; console.log('✅ 选择界面已显示'); } // 不播报选择提示,让用户直接看到选择界面 console.log('🎭 选择界面已显示,用户可以随时选择'); // 添加提示说明用户可以随时选择 const choicesHeader = document.querySelector('.choices-header h3'); if (choicesHeader) { choicesHeader.textContent = '🎭 在开始朗读前,请选择故事的走向!'; } const choicesSubtitle = document.querySelector('.choices-header p'); if (choicesSubtitle) { choicesSubtitle.textContent = '请选择一个选项,这将决定故事的发展方向。您可以在语音朗读过程中随时选择:'; } } makeChoice(choiceIndex) { if (!this.waitingForChoice || choiceIndex < 0 || choiceIndex >= this.currentChoices.length) { return; } const choice = this.currentChoices[choiceIndex]; // 不设置waitingForChoice = false,让用户可以继续选择 // 记录选择历史(只记录最后一次选择) const currentSectionKey = ['beginning', 'middle', 'ending'][this.currentSection]; // 移除当前段落之前的选择记录 this.choicesHistory = this.choicesHistory.filter(record => !(record.storyId === this.currentStory.id && record.section === currentSectionKey) ); // 添加新的选择记录 this.choicesHistory.push({ storyId: this.currentStory.id, section: currentSectionKey, choice: choice.choiceText, consequence: choice.consequence, timestamp: new Date().toISOString() }); // 更新UI显示选择结果(只能选择一个选项,可以更换选择) const choiceButtons = document.querySelectorAll('.choice-btn'); choiceButtons.forEach((btn, index) => { // 清除所有按钮的选择状态 btn.classList.remove('clicked'); btn.removeAttribute('data-selected'); // 只标记当前选择的按钮 if (index === choiceIndex) { btn.classList.add('clicked'); btn.setAttribute('data-selected', 'true'); } }); // 显示选择反馈 const feedbackPosition = document.getElementById('choiceFeedback'); if (feedbackPosition) { feedbackPosition.innerHTML = `

🎉 ${choice.effect}

`; console.log('📝 选择反馈已更新:', choice.effect); } // 停止之前的语音播报 if (window.virtualTeacher) { window.virtualTeacher.stopSpeaking(); } // 先显示分支剧情,然后按顺序播报语音 console.log('🎭 立即显示分支剧情:', choice.consequence); this.showBranchingNarrative(choice.consequence); // 语音播报选择的选项文字,读完后再读分支剧情 if (window.virtualTeacher && this.isVoiceEnabled) { const cleanChoiceText = choice.choiceText.replace(/[🌟🐾🧺🌅🌞🌆🎣🎈👥🚪🌲🧱💨🤝🏡🌧️🎣🏃🏠🌾🤝🏃]/g, ''); console.log('🔊 开始朗读选项文字:', cleanChoiceText); // 朗读选项的文字内容,读完后再读分支剧情 window.virtualTeacher.speak(cleanChoiceText, { rate: this.desiredRate, pitch: 1.0, onend: () => { console.log('✅ 选项文字朗读完成,停顿后读分支剧情'); // 停顿2秒后读分支剧情 setTimeout(() => { const branchingNarrative = this.currentStory.branchingNarratives?.[choice.consequence]; if (branchingNarrative) { console.log('🔊 开始朗读分支剧情:', branchingNarrative.text); window.virtualTeacher.speak(branchingNarrative.text, { rate: this.desiredRate, pitch: 1.0, onend: () => { console.log('✅ 分支剧情朗读完成'); // 停顿2秒后提示继续 setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 2000); }, onerror: () => { console.log('⚠️ 分支剧情语音播报出错,直接提示继续'); setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 1000); } }); } }, 2000); }, onerror: () => { console.log('⚠️ 选项文字语音播报出错,直接读分支剧情'); // 如果选项文字播报出错,直接读分支剧情 setTimeout(() => { const branchingNarrative = this.currentStory.branchingNarratives?.[choice.consequence]; if (branchingNarrative) { console.log('🔊 开始朗读分支剧情:', branchingNarrative.text); window.virtualTeacher.speak(branchingNarrative.text, { rate: this.desiredRate, pitch: 1.0, onend: () => { console.log('✅ 分支剧情朗读完成'); setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 2000); }, onerror: () => { console.log('⚠️ 分支剧情语音播报也出错,直接提示继续'); setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 1000); } }); } }, 1000); } }); } // 备用方案:如果3秒后还没有开始读分支剧情,强制开始 this.branchingTimeout = setTimeout(() => { console.log('⚠️ 备用方案:强制开始读分支剧情'); const branchingNarrative = this.currentStory.branchingNarratives?.[choice.consequence]; if (branchingNarrative) { console.log('🔊 备用方案开始朗读分支剧情:', branchingNarrative.text); window.virtualTeacher.speak(branchingNarrative.text, { rate: this.desiredRate, pitch: 1.0, onend: () => { console.log('✅ 备用方案分支剧情朗读完成'); setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 2000); }, onerror: () => { console.log('⚠️ 备用方案分支剧情语音播报也出错,直接提示继续'); setTimeout(() => { window.virtualTeacher.speak("点击继续故事按钮来继续阅读"); }, 1000); } }); } }, 3000); } showBranchingNarrative(consequenceKey) { console.log('🔍 查找分支剧情:', consequenceKey); const branchingNarrative = this.currentStory.branchingNarratives?.[consequenceKey]; if (!branchingNarrative) { console.error('❌ 找不到分支剧情:', consequenceKey); console.log('📚 当前故事的分支剧情:', this.currentStory.branchingNarratives); return; } console.log('✅ 找到分支剧情:', branchingNarrative); // 停止之前的语音播报 if (window.virtualTeacher) { window.virtualTeacher.stopSpeaking(); } const branchingContent = document.getElementById('branchingContent'); const branchNarrative = document.getElementById('branchNarrative'); if (branchNarrative) { branchNarrative.innerHTML = `
🎭 你的选择带来了新的故事发展:
${branchingNarrative.text}
`; console.log('📖 分支剧情内容已更新:', branchingNarrative.text); } if (branchingContent) { branchingContent.style.display = 'block'; } // 语音播报现在在makeChoice方法中处理,这里不再播报 } continueFromBranch() { // 清除之前的定时器 if (this.branchingTimeout) { clearTimeout(this.branchingTimeout); this.branchingTimeout = null; } // 隐藏并清除分支内容 const branchingContent = document.getElementById('branchingContent'); const branchNarrative = document.getElementById('branchNarrative'); const storyChoices = document.getElementById('storyChoices'); const choicesContainer = document.getElementById('choicesContainer'); const choiceFeedback = document.getElementById('choiceFeedback'); if (branchingContent) branchingContent.style.display = 'none'; if (storyChoices) storyChoices.style.display = 'none'; // 清除所有内容 if (branchNarrative) branchNarrative.innerHTML = ''; if (choicesContainer) choicesContainer.innerHTML = ''; if (choiceFeedback) choiceFeedback.innerHTML = ''; this.waitingForChoice = false; // 点击"继续故事"后,总是进入下一段故事 setTimeout(() => { this.nextSection(); }, 1000); // 语音反馈 if (window.virtualTeacher && this.isVoiceEnabled) { window.virtualTeacher.speak("很好!故事继续发展..."); } } updateControlButtons() { const prevBtn = document.getElementById('prevSection'); const nextBtn = document.getElementById('nextSection'); const readBtn = document.getElementById('readCurrentSection'); // 更新按钮状态 if (prevBtn) prevBtn.disabled = this.currentSection === 0; const sections = ['beginning', 'middle', 'ending']; if (nextBtn) nextBtn.disabled = this.currentSection >= sections.length - 1; if (readBtn) readBtn.disabled = this.waitingForChoice; // 更新按钮文字 if (readBtn) { const readText = readBtn.querySelector('.btn-text'); if (readText) { readText.textContent = this.waitingForChoice ? '请先做选择' : '朗读本段'; } } } } // 创建全局实例 window.aiStorytelling = new AIStorytelling(); // 防止页面刷新时状态丢失 window.addEventListener('beforeunload', () => { if (window.virtualTeacher) { window.virtualTeacher.stopAllSpeech(); } });