diff --git a/ui-src/src/components/SceneTheater.vue b/ui-src/src/components/SceneTheater.vue index be9c01d..82c80dd 100644 --- a/ui-src/src/components/SceneTheater.vue +++ b/ui-src/src/components/SceneTheater.vue @@ -43,10 +43,6 @@ - - - 开始 › - @@ -84,7 +80,8 @@ export default { mounted() { this.speaking = true speak(this.content, this.audio) - setTimeout(() => { this.speaking = false }, Math.min(3000, this.content.length * 300)) + // v2.1:朗读结束自动进入决策幕(「跳过」仍可手动跳过) + setTimeout(() => { this.speaking = false; this.$emit('done') }, Math.min(3000, this.content.length * 300)) }, beforeUnmount() { stopSpeak() @@ -126,6 +123,4 @@ export default { @keyframes t-word { 0% { opacity: 0; transform: translateY(12rpx); } 100% { opacity: 1; transform: translateY(0); } } .theater-py { font-size: 20rpx; color: #ff6b35; line-height: 1.3; height: 28rpx; } .theater-ch { font-size: 34rpx; line-height: 1.5; color: #5b4636; } -.theater-actions { display: flex; justify-content: center; margin-top: 32rpx; position: relative; z-index: 2; } -.theater-go { font-size: 34rpx; min-width: 240rpx; animation: t-pop 0.5s ease 1.2s backwards; } diff --git a/ui-src/src/components/StoryPlayer.vue b/ui-src/src/components/StoryPlayer.vue index 07a3758..379cc4d 100644 --- a/ui-src/src/components/StoryPlayer.vue +++ b/ui-src/src/components/StoryPlayer.vue @@ -9,7 +9,7 @@ - + 📖 旁白 @@ -136,7 +136,7 @@ export default { .story-lines { display: flex; flex-direction: column; gap: 24rpx; padding-bottom: 24rpx; } .story-line { opacity: 0; transition: opacity 0.4s; } .story-line.active { opacity: 1; } -.story-line.done { opacity: 0.55; } +.story-line.fading { opacity: 0.35; } .bubble { border-radius: 24rpx; padding: 24rpx 28rpx; box-shadow: 0 4rpx 16rpx rgba(91, 70, 54, 0.08); } .bubble-name { font-size: 24rpx; font-weight: 700; color: #ff6b35; margin-bottom: 8rpx; } .nar-bubble { background: #fff3d6; margin-left: 40rpx; margin-right: 40rpx; } diff --git a/ui-src/src/pages/play/play.vue b/ui-src/src/pages/play/play.vue index 9d8dcb2..b63e0c0 100644 --- a/ui-src/src/pages/play/play.vue +++ b/ui-src/src/pages/play/play.vue @@ -45,6 +45,11 @@ + + + + + @@ -170,7 +175,10 @@ export default { soundOn: isSoundEnabled(), showIntro: false, sceneFx: '', - branchTimer: null + branchTimer: null, + replyTimer: null, + playingFinal: false, + finalNode: null } }, onLoad(options) { @@ -179,6 +187,7 @@ export default { }, onUnload() { if (this.branchTimer) clearTimeout(this.branchTimer) + if (this.replyTimer) clearTimeout(this.replyTimer) }, computed: { scene() { @@ -207,6 +216,9 @@ export default { }, introProps() { return this.detail ? entryProps(this.detail.entry) : [] + }, + finalScript() { + return this.finalNode ? parseScript(this.finalNode.script) : null } }, methods: { @@ -266,6 +278,8 @@ export default { if (this.isStoryNode) { this.reply = fb this.showOptions = false // 提交后隐藏选项区,防重复点击 + // v2.1:回应气泡约 3 秒自动继续(点击「继续」立即继续) + this.replyTimer = setTimeout(() => this.autoContinue(), 3000) } else { this.feedback = fb } @@ -279,8 +293,15 @@ export default { route_steps: this.routeSteps, final: data.final }) - playSound('finish') - uni.redirectTo({ url: '/pages/result/result' }) + this.choosing = false + // v2.1:终局节点有剧本 → 先演绎结局台词再跳结算;无剧本直接跳(回退) + if (data.final.final_node && parseScript(data.final.final_node.script)) { + this.finalNode = data.final.final_node + this.playingFinal = true + } else { + playSound('finish') + uni.redirectTo({ url: '/pages/result/result' }) + } } else { this.choosing = false } @@ -288,7 +309,15 @@ export default { this.choosing = false } }, + autoContinue() { + if (this.reply && !this.choosing) this.continuePlay() + }, + gotoResult() { + playSound('finish') + uni.redirectTo({ url: '/pages/result/result' }) + }, continuePlay() { + if (this.replyTimer) { clearTimeout(this.replyTimer); this.replyTimer = null } if (this.isStoryNode) { this.curNode = this.reply.next this.reply = null