feat: chapter select system, multi-chapter support, scene manager refactor, and docs update

This commit is contained in:
2026-06-09 11:35:11 +08:00
parent 655b9a23d0
commit ace5ed1fb3
14 changed files with 413 additions and 17 deletions

View File

@@ -433,29 +433,56 @@ GainNode 的 ramp 目标值 = `Math.min(bgmVolume, bgmDuckLevel × bgmVolume)`
- [x] `src/App.vue` — 右上角全屏按钮,与"菜单"按钮并排;`fullscreenchange` 同步图标状态
- [x] `FUTURE.md` — 远期扩展笔记Pointer Lock、自动全屏、UI 自动隐藏、移动端适配等)
### P8 章节选择 — 通关后跳转(待实现)
### P8 章节选择 — 到达即解锁,主菜单+通关后跳转 ✅ 已完成 2026-06-09
目标:玩家通关后,可从中途任意章节起始点重新开始。每个章节记录一个入口场景 ID展示章节缩略图和标题
目标:玩家可从中途任意章节起始点重新开始。到达章节入口即解锁,主菜单和通关后均可进入章节选择界面
**核心规则:**
| 规则 | 说明 |
|------|------|
| **解锁方式** | 到达即解锁 — `goToScene` 中检测当前场景所属章节,立即标记解锁并持久化到 IndexedDB |
| **变量状态** | 跳转时套用该章的 `defaultVariables`,未定义时 fallback 到全局 `variables`;确保条件分支不锁死 |
| **入口** | 主菜单"章节选择"按钮 + 通关后"章节选择"按钮,两处均可进入 |
**数据结构设计:**
```json
{
"startScene": "intro",
"variables": { "trust": 50, "courage": 0, "investigation": 0 },
"chapters": [
{ "id": "ch1", "label": "第一章:醒来", "startScene": "intro", "thumbnail": "/images/ch1.jpg" },
{ "id": "ch2", "label": "第章:抉择", "startScene": "left_door", "thumbnail": "/images/ch2.jpg" }
{
"id": "ch1", "label": "第章:醒来", "startScene": "intro",
"thumbnail": "/images/ch1.jpg",
"defaultVariables": { "trust": 50, "courage": 0, "investigation": 0 }
},
{
"id": "ch2", "label": "第二章:调查", "startScene": "desk_detail",
"thumbnail": "/images/ch2.jpg",
"defaultVariables": { "trust": 60, "courage": 10, "investigation": 1 }
},
{
"id": "ch3", "label": "第三章:终局", "startScene": "qte_success",
"thumbnail": "/images/ch3.jpg",
"defaultVariables": { "trust": 70, "courage": 20, "investigation": 2 }
}
]
}
```
**实现清单:**
- [ ] `engine/types.ts``GameData.chapters` 字段、`ChapterInfo` 接口
- [ ] `engine/systems/SaveSystem.ts`章节解锁状态持久化(已通关章节记录)
- [ ] `src/components/ChapterSelect.vue` — 章节选择界面:缩略图网格 + 标题 + 锁定/解锁状态
- [ ] `engine/core/Engine.ts``startChapter(chapterId)` 方法,跳转到指定章节起始场景
- [ ] `src/App.vue` — 主菜单:新游戏 / 章节选择 / 继续
- [ ] 验证:通关后章节解锁、从章节入口跳转正确、未解锁章节灰显
- [x] `engine/types.ts``GameData.chapters` 字段、`ChapterInfo` 接口(含 `defaultVariables`
- [x] `engine/systems/SaveSystem.ts`DB v3 新增 `unlocks` 表;`unlockChapter`/`getUnlockedChapters`
- [x] `engine/core/SceneManager.ts``chapters` 存储、`getChapterBySceneId`/`getChapter` 查询
- [x] `engine/core/Engine.ts``goToScene` 检测场景所属章节 → `chapterUnlock` 事件;`startChapter` 套用 `defaultVariables` 并重置 flags/history
- [x] `src/components/ChapterSelect.vue` — 章节选择 UI缩略图网格 + 标题 + 锁定/解锁
- [x] `src/stores/gameStore.ts``chapters`/`unlockedChapterIds`/`showChapterSelect` 状态
- [x] `src/App.vue` — 主菜单"章节选择"按钮 + 游戏结束"章节选择"按钮
- [x] `public/scenes/demo.json` — 3 章定义(含 defaultVariables 和 thumbnail
- [x] `public/images/ch{1,2,3}.jpg` — 章节缩略图
- [x] 验证TypeScript + Vite build 通过
### P9 跳过已看 + 倍速播放(待实现)