# P15 结局画廊 + 章节回顾 + 分支图

## 概述

通关后的"重玩驱动力"系统，对标 Detroit: Become Human 的流程回顾功能。三个概念递进：**分支图**是底座，**章节回顾**是在分支图上叠加统计和提示，**结局画廊**是独立入口。

---

## 1. 结局画廊 (Ending Gallery)

### 形态

一张缩略图网格，每张卡片对应一个结局：

```
┌────────────┐ ┌────────────┐ ┌────────────┐
│  信任的伙伴   │ │  独行之路    │ │     ?      │
│  (已解锁)    │ │  (已解锁)    │ │  🔒 未解锁   │
│ ［画面缩略图］│ │ ［画面缩略图］ │ │ ［灰色剪影］  │
└────────────┘ └────────────┘ └────────────┘
```

已解锁：显示结局场景截图 + 标题。未解锁：显示锁图标 + 灰色占位。

### 数据层

```json
// demo.json 顶层
{
  "endings": [
    {
      "id": "trust_end",
      "label": "信任的伙伴",
      "sceneId": "trust_ending",
      "thumbnail": "/images/end_trust.jpg"
    },
    {
      "id": "alone_end",
      "label": "独行之路",
      "sceneId": "alone_ending",
      "thumbnail": "/images/end_alone.jpg"
    }
  ]
}
```

### 判断逻辑

引擎 `goToScene` → 自动 mark `visitedSceneIds.add(scene.id)`。画廊判断：

```
图库卡片解锁 = visitedSceneIds.has(ending.sceneId)
```

不独立建"结局表"，共用 visited 追踪。场景的 `id` 和结局的 `sceneId` 对得上就算到达过。

---

## 2. 分支图 (Branch Map)

### 形态

一张**只读的 Vue Flow 流程图**，展示该章节所有可能的场景路径。和编辑器一样是节点+连线，但**不能编辑**。

| 状态 | 样式 |
|------|------|
| 已走过 | 绿色实心节点 + 绿色连线 |
| 未走过 | 灰色虚线边框节点 + 灰色连线 |
| 当前查看的章节 | 高亮标注 |

### 数据来源

- **全部路径**：从 `SceneManager.getScenes()` 获取所有场景，根据 choices / nextScene / QTE 生成所有可能的连线
- **已走路径**：对比 `visitedSceneIds`，匹配上的标绿
- **BFS 可达范围**：从章节的 `startScene` 做 BFS，得到该章的理论可达节点集合（作为分母算完成度）

### 节点定义

```
intro ──→ left_door ──→ trust_ending (结局)      ← 如果走过，绿色
   │                        ↘ alone_ending (结局)  ← 如果走过，绿色
   │                                ↗
   └──→ stay ───────────────────┘
```

---

## 3. 章节回顾 (Chapter Recap)

### 形态

分支图 + 两个信息层叠加：

**完成度百分比：**

```
┌─────────────────────────────────────┐
│  第一章 "醒来"                       │
│  ████████████░░░░░░░░  3/7 (43%)     │
│  已发现 3/7 个场景                    │
└─────────────────────────────────────┘
```

分母：从该章 `startScene` BFS 遍历能得到的所有场景数。分子：这些场景中 visited 了哪些。

**条件提示：**

未走过的灰色节点上标出解锁条件：

```
┌──────────────────┐
│  🔒 secret_ending │
│  需要 trust >= 80  │
└──────────────────┘
```

引擎读取目标节点的 choice 或 hotspot 对应的 `conditions`，展示第一个未满足的条件的提示文案。

---

## 交互流程

```
游戏结束
  │
  ├─→ 结局画廊（检查本局新解锁了哪些结局卡片）
  │     │
  │     └─→ 点击某章 → 章节回顾
  │           │
  │           ├─→ 查看完整度 "3/7 (43%)"
  │           ├─→ 看分支图："这条路我没走过"
  │           └─→ 看条件提示："需要 trust >= 80"
  │
  └─→ 重玩动力："下次试试提升 trust 来看看 secret_ending"
```

---

## 技术要点

| 要点 | 做法 |
|------|------|
| 路径追踪 | `visitedSceneIds: Set<string>`，`goToScene` 中 `visited.add(scene.id)` |
| 结局判定 | 共用 `visitedSceneIds`，不独立建表 |
| 完成度分母 | BFS 从 `startScene` 遍历 `scenes` 对象，得到可达集合 |
| 条件提示 | 查对应 choice/hotspot 的 `conditions` 数组，取第一个未满足的条件 |
| 分支图渲染 | Vue Flow 只读模式 + `nodes`/`edges` 动态构建 + visited 着色 |
| 持久化 | SaveSystem `visited` 表（DB v6） |
