From 0dbe1b097d6274a7ddd0164f0d51852be9e36ef3 Mon Sep 17 00:00:00 2001 From: cocos02 Date: Mon, 8 Jun 2026 21:48:47 +0800 Subject: [PATCH] feat: video loop support for hotspot scenes, demo updates, docs, and engine fixes --- ROADMAP.md | 70 +++++++++++++++++++++++++++--------- engine/core/Engine.ts | 39 ++++++++++++++++++-- engine/core/VideoManager.ts | 5 +++ engine/types.ts | 2 ++ public/scenes/demo.json | 8 +++-- public/videos/stay_loop.mp4 | Bin 0 -> 37699 bytes 6 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 public/videos/stay_loop.mp4 diff --git a/ROADMAP.md b/ROADMAP.md index 92230f3..d5b9dd2 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -249,18 +249,32 @@ interface SaveData { - [x] `public/scenes/demo.json` — 新增图片热点场景 `investigation_site` + 视频热点场景 `corridor` - [x] 验证:图片热区点击触发、视频热区按时出现/消失、条件过滤、hover 高亮 -### P5 选择等待循环 — 视频结束循环播放(待实现) +### P5 选择等待循环 — 单文件内时间锚点无缝循环 ✅ 已完成 2026-06-08 -目标:视频结束后不暂停画面,而是无缝切换到一段循环视频(Idle Loop),选项浮在循环画面之上, -消除"画面静止等选择"的割裂感,提升电影感。这是《底特律:变人》《Late Shift》等商业游戏的标配做法。 +目标:视频结束后画面不暂停,而是在同一文件内通过 `loopStart`/`loopEnd` 时间锚点实现无切换循环, +选项浮在循环画面之上。和《底特律:变人》《The Dark Pictures Anthology》等商业游戏的做法一致。 + +**为什么不用单独 loop 文件做 cross-fade:** +- 任何文件切换(硬切或淡入)都会产生可感知的割裂感 +- 商业游戏的循环效果本质上就是同一帧内 `video.currentTime = loopStart`,完全透明 +- 同一文件内 seek 只在下一个 timeupdate 触发(~250ms),但对 ≥2 秒的循环区间来说误差 <5%,肉眼无感 + +**做法对比:** + +| 方案 | 体验 | +|------|------| +| ~~主视频 → cross-fade → loopVideo 文件~~ | 两画面重叠 300ms,**割裂** | +| ~~主视频 → 硬切 → loopVideo 文件~~ | 一帧黑/闪,依赖浏览器 | +| **同一文件内 `loopStart/loopEnd` seek** | **完全无缝,AAA 游戏标准** | **场景数据设计:** ```json { "id": "tense_moment", - "videoUrl": "/videos/tense.mp4", - "loopVideoUrl": "/videos/tense_loop.mp4", + "videoUrl": "/videos/tense_full.mp4", + "loopStart": 8.0, + "loopEnd": 10.0, "choices": [ { "text": "冒险救人", "targetScene": "rescue" }, { "text": "悄悄离开", "targetScene": "flee" } @@ -268,24 +282,46 @@ interface SaveData { } ``` +素材制作流程:导演剪辑时将主剧情段 + 循环段合成为一个 MP4 文件,比如: +``` +0:00 ~ 8:00 正常剧情演绎 +8:00 ~ 10:00 循环片段(角色呼吸、张望)── 循环起点 loopStart=8, loopEnd=10 +``` + **工作流程:** ``` -主视频 A槽播放 ──→ ended ──→ B槽切换 loopVideo (loop=true) + 淡入 ──→ 显示选项 - │ - 用户点击选择 ────┘ - │ - 停止循环 → 切换到目标场景 +┌─ 主视频正常播放(0s → loopStart) +│ +├─ time >= loopStart → 标记"已到达循环区间" +│ └─ timeupdate 持续检测:time >= loopEnd → video.currentTime = loopStart(无任何过渡) +│ └─ 无限循环中... +│ │ +│ ├─ 用户选择 ──→ break loop → switchTo(nextScene) +│ │ +│ ├─ 视频 ended → 自动触发循环区间 +│ │ +│ └─ 选项面板在循环开始时浮出 +│ +└─ 无 loopStart 的场景 → 保持现有行为(结束后暂停,等待选择) ``` -**实现清单(基于现有 A/B 双缓冲架构,改动量小):** +**关键设计细节:** -- [ ] `engine/types.ts` — `SceneNode.loopVideoUrl?: string` -- [ ] `engine/core/VideoManager.ts` — `playLoop(url)` 新方法(复用 inactive 槽,`loop=true` + 交叉淡化) -- [ ] `engine/core/Engine.ts` — 视频 ended 时检测 `loopVideoUrl`,有则调用 `playLoop` 而非直接触发选项;用户选择后停止循环 -- [ ] `src/components/ChoicePanel.vue` — 无改动(选项已浮在视频层之上) -- [ ] `public/scenes/demo.json` — 示例场景添加循环视频 -- [ ] 验证:主视频结束 → 无缝循环 → 选项中循环播放 → 选择后停止 → 下一场景 +- 检测循环完全依赖 `timeupdate` 事件,无需 `requestAnimationFrame` 或额外定时器——浏览器 ~250ms 的 timeupdate 间隔对 ≥2s 的循环段误差可忽略 +- 循环中 A/B 预加载仍然工作:inactive slot 加载第一个候选目标场景,用户选择后 cross-fade 过去 +- `loopStart` 既是触发选项显示的时机(视频到达此处时 emit `choiceRequest`)也是循环起点 +- `loopEnd` 为循环终点,到达后 seek 回 `loopStart` +- 若只设 `loopStart` 不设 `loopEnd`,则循环区间为 `loopStart → 视频结尾` + +**实现清单:** + +- [x] `engine/types.ts` — `SceneNode.loopStart?: number`, `loopEnd?: number` +- [x] `engine/core/VideoManager.ts` — 新增 `seekTo(time)` 方法 +- [x] `engine/core/Engine.ts` — `checkLoop(time)` 在 timeupdate 中检测循环区间;`onVideoEnd` 循环活跃时跳过;`goToScene` 重置 `loopActive` +- [x] `public/scenes/demo.json` — `stay` 场景添加 loopStart=3, loopEnd=6, 循环中显示选项 +- [x] `public/videos/stay_loop.mp4` — 6s 测试视频(0-3s 蓝色正文 + 3-6s 绿色循环段) +- [x] 验证:正文播放完毕 → 进入循环 → 选项浮现 → 画面无缝来回 → 选择后跳转 ### P6 独立背景音乐 — 画面循环不打断 BGM(待实现) diff --git a/engine/core/Engine.ts b/engine/core/Engine.ts index 05baf99..e6d3ef1 100644 --- a/engine/core/Engine.ts +++ b/engine/core/Engine.ts @@ -21,6 +21,7 @@ export class Engine { private qteTriggered = false private qteResolved = false private justCameFromImage = false + private loopActive = false constructor() { this.sceneManager = new SceneManager() @@ -29,7 +30,7 @@ export class Engine { this.choiceSystem = new ChoiceSystem() this.qteSystem = new QTESystem() - this.videoManager.onTimeUpdate(this.checkQTE) + this.videoManager.onTimeUpdate(this.onTimeUpdate) } on(event: EngineEvent, handler: EventHandler) { @@ -56,6 +57,7 @@ export class Engine { this.currentScene = scene this.qteTriggered = false this.qteResolved = false + this.loopActive = false if (scene.onEnter) { this.stateManager.apply(scene.onEnter) @@ -106,12 +108,14 @@ export class Engine { } } - private checkQTE = (time: number) => { + private onTimeUpdate = (time: number) => { const scene = this.currentScene if (!scene) return this.checkHotspotTime(scene, time) + this.checkLoop(time) + // QTE check after loop check, so loop doesn't interfere with QTE if (!scene.qte || this.qteTriggered) return if (time >= scene.qte.triggerTime) { this.qteTriggered = true @@ -154,6 +158,33 @@ export class Engine { } } + private checkLoop(time: number) { + const scene = this.currentScene + if (!scene?.loopStart) return + + if (!this.loopActive && time >= scene.loopStart) { + this.loopActive = true + const validChoices = this.getValidChoices(scene) + if (validChoices.length > 0) { + this.emit('choiceRequest', validChoices) + this.choiceSystem.start( + validChoices, + (timerState) => { + this.emit('choiceTimer', timerState) + }, + (defaultChoice) => { + this.emit('choiceTimeout', defaultChoice) + this.makeChoice(defaultChoice) + } + ) + } + } + + if (this.loopActive && scene.loopEnd && time >= scene.loopEnd) { + this.videoManager.seekTo(scene.loopStart) + } + } + private checkHotspotTime(scene: SceneNode, time: number) { if (!scene.hotspots || scene.hotspots.length === 0) return @@ -197,6 +228,8 @@ export class Engine { } private onVideoEnd(scene: SceneNode) { + if (this.loopActive) return + const validChoices = this.getValidChoices(scene) if (validChoices.length > 0) { @@ -220,7 +253,6 @@ export class Engine { this.endGame() } } else if (scene.hotspots?.length) { - // hotspot-only scene: wait for user to click a hotspot return } else { this.endGame() @@ -257,6 +289,7 @@ export class Engine { endGame() { this.ended = true + this.loopActive = false this.qteSystem.cancel() this.emit('gameEnd') } diff --git a/engine/core/VideoManager.ts b/engine/core/VideoManager.ts index 293bef1..a723f3b 100644 --- a/engine/core/VideoManager.ts +++ b/engine/core/VideoManager.ts @@ -149,6 +149,11 @@ export class VideoManager { return this.active ?? null } + seekTo(time: number) { + if (!this.active) return + this.active.currentTime = time + } + onEnd(cb: VideoEndCallback) { this.onEndCallback = cb } diff --git a/engine/types.ts b/engine/types.ts index 630ad0c..e975bd1 100644 --- a/engine/types.ts +++ b/engine/types.ts @@ -9,6 +9,8 @@ export interface SceneNode { qte?: QTEDefinition nextScene?: string onEnter?: Effect[] + loopStart?: number + loopEnd?: number } export interface Choice { diff --git a/public/scenes/demo.json b/public/scenes/demo.json index aa9d466..7cce0b5 100644 --- a/public/scenes/demo.json +++ b/public/scenes/demo.json @@ -183,9 +183,13 @@ }, "stay": { "id": "stay", - "videoUrl": "/videos/stay.mp4", + "videoUrl": "/videos/stay_loop.mp4", "subtitleUrl": "/subtitles/stay.vtt", - "nextScene": "alone_ending" + "loopStart": 3.0, + "loopEnd": 6.0, + "choices": [ + { "text": "站起来离开", "targetScene": "alone_ending" } + ] }, "trust_ending": { "id": "trust_ending", diff --git a/public/videos/stay_loop.mp4 b/public/videos/stay_loop.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..0344a63f251c02bc777ebac5306edead454e5c45 GIT binary patch literal 37699 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