feat: battle system, state manager enhancements, engine and demo updates
This commit is contained in:
159
ROADMAP.md
159
ROADMAP.md
@@ -144,6 +144,165 @@ QTE 场景和过渡/路由场景被过滤,子节点上浮一级。
|
||||
- [x] `src/components/StoryGallery.vue` — `isKeyMoment()` 三层逻辑 + `collectKeyTargets()` 扁平化非关键节点
|
||||
- [x] 验证:TypeScript + Vite build 通过
|
||||
|
||||
### P27 全局计时器 — 跨场景时间压力(待实现)
|
||||
|
||||
目标:跨场景倒计时,时间用尽强制跳转。独立的 `TimerSystem` 类 + 三个新 Effect 类型,
|
||||
支持启动/停止/重置/加减时间。
|
||||
|
||||
**Effect 类型:**
|
||||
|
||||
| Effect type | 参数 | 说明 |
|
||||
|-------------|------|------|
|
||||
| `startTimer` | `duration`(秒), `expireScene` | 启动倒计时。如已存在则重置 |
|
||||
| `stopTimer` | — | 暂停计时器 |
|
||||
| `addTime` | `value`(秒) | 增加剩余时间(正数)或扣减(负数) |
|
||||
|
||||
**使用场景:**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "chapter_start",
|
||||
"onEnter": [
|
||||
{ "type": "startTimer", "duration": 3600, "value": 3600, "target": "timeout_ending" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**TimerSystem 核心逻辑:**
|
||||
|
||||
```typescript
|
||||
class TimerSystem {
|
||||
private remaining: number = 0
|
||||
private expireScene: string = ''
|
||||
private intervalId: ReturnType<typeof setInterval> | null = null
|
||||
private onExpire: ((sceneId: string) => void) | null = null
|
||||
|
||||
start(duration: number, expireScene: string) { ... }
|
||||
stop() { ... }
|
||||
addTime(seconds: number) { ... }
|
||||
getRemaining(): number { ... }
|
||||
}
|
||||
```
|
||||
|
||||
setInterval 每秒递减,剩余 ≤0 时调用 `onExpire(expireScene)`。
|
||||
|
||||
**UI 显示:** PlaybackBar 右下角 `MM:SS` 格式,最后一分钟变红。
|
||||
|
||||
**实现清单:**
|
||||
|
||||
- [ ] `engine/systems/TimerSystem.ts` — **新建** — 计时器核心逻辑
|
||||
- [ ] `engine/types.ts` — Effect 新增 `startTimer`/`stopTimer`/`addTime` 类型
|
||||
- [ ] `engine/core/StateManager.ts` — `apply` 中处理新 Effect
|
||||
- [ ] `engine/core/Engine.ts` — 集成 `TimerSystem`;`startChapter` 停止旧 Timer
|
||||
- [ ] `engine/systems/SaveSystem.ts` — 存档/读档包含 Timer 状态
|
||||
- [ ] `src/components/PlaybackBar.vue` — HUD 显示倒计时
|
||||
|
||||
### P28 随机路由 — 变量初始值/场景随机选择(待实现)
|
||||
|
||||
目标:`nextScene` / 变量初始值支持随机选择,每次玩法不同。
|
||||
|
||||
### P29 背包/装备系统 — 物品持有影响叙事(待实现)
|
||||
|
||||
目标:玩家可持有物品,物品影响 `conditions` 判断、选择可见性、场景解锁。
|
||||
|
||||
### P30 通关评分/反馈 — 结算面板展示统计(待实现)
|
||||
|
||||
目标:通关后展示玩家行为统计(线索数、成就数、结局数)。DeathPanel 升级为通用的 `ResultPanel`,死亡和通关统一走这里。
|
||||
|
||||
**数据设计(GameData 顶层):**
|
||||
|
||||
```json
|
||||
{
|
||||
"stats": [
|
||||
{ "label": "线索发现", "variable": "investigation", "max": 5 },
|
||||
{ "label": "QTE 成功次数", "variable": "qte_succeeded" },
|
||||
{ "label": "达成结局数", "type": "endingsCount" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `label` | 统计项名称 |
|
||||
| `variable` | 从 `variables` 读值 |
|
||||
| `max` | 满分(可选),用于进度条 |
|
||||
| `type: "endingsCount"` | 特殊统计 — `visitedSceneIds ∩ endings[].sceneId` 计数 |
|
||||
|
||||
**实现清单:**
|
||||
|
||||
- [ ] `engine/types.ts` — `GameData.stats?: StatDef[]`
|
||||
- [ ] `src/components/DeathPanel.vue` → 升级为 `ResultPanel.vue`
|
||||
- [ ] `src/App.vue` — `gameEnd` 触发后展示 ResultPanel
|
||||
|
||||
### P31 战斗 HUD + 结算面板 — RPG HUD 流派 ✅ 已完成 2026-06-12
|
||||
|
||||
目标:战斗场景中展示角色属性 HUD(头像 + HP/MP 条 + 数值),胜利后弹出结算面板。
|
||||
走 RPG HUD 流派,非极简派。战败不做结算面板,直接走战败叙事。
|
||||
|
||||
**SceneNode 新增字段:**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "combat",
|
||||
"videoUrl": "combat/combat.mp4",
|
||||
"qte": { ... },
|
||||
"battleHUD": [
|
||||
{
|
||||
"label": "你",
|
||||
"portrait": "images/player.jpg",
|
||||
"stats": [
|
||||
{ "variable": "player_hp", "label": "HP", "max": 100 },
|
||||
{ "variable": "player_mp", "label": "MP", "max": 50 },
|
||||
{ "variable": "combo_score", "label": "连击" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "敌人",
|
||||
"portrait": "images/enemy.jpg",
|
||||
"stats": [
|
||||
{ "variable": "enemy_hp", "label": "HP", "max": 100 }
|
||||
]
|
||||
}
|
||||
],
|
||||
"battleResult": {
|
||||
"title": "战斗胜利!",
|
||||
"stats": [
|
||||
{ "label": "剩余生命", "variable": "player_hp" },
|
||||
{ "label": "QTE 成功次数", "variable": "qte_succeeded" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**BattleHUD 字段说明:**
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `label` | 角色名称 |
|
||||
| `portrait` | 角色头像路径 |
|
||||
| `stats` | 属性数组。`variable`/`label`/`max`/`style`(`"bar"` 或 `"number"`,缺省时根据有无 `max` 自动判断) |
|
||||
|
||||
**布局:** 角色头像左侧,stats 竖排叠在头像右侧。多角色水平排列在屏幕一侧。
|
||||
|
||||
**组件:**
|
||||
|
||||
| 组件 | 说明 |
|
||||
|------|------|
|
||||
| `BattleHUD.vue` | 战斗场景中显示角色属性条,`variables` 实时响应 |
|
||||
| `BattleResult.vue` | 胜利结算面板 — 标题 + stats + "继续"按钮 → 下一场景 |
|
||||
|
||||
**实现清单:**
|
||||
|
||||
- [x] `engine/types.ts` — `BattleHUDStat` / `BattleHUDEntry` / `BattleResultStat` / `BattleResultDef` 接口
|
||||
- [x] `src/components/BattleHUD.vue` — **新建** — 角色头像 + stats 进度条/数值,i18n labelKey
|
||||
- [x] `src/components/BattleResult.vue` — **新建** — 胜利结算面板 + titleKey + "继续"按钮
|
||||
- [x] `src/stores/gameStore.ts` — `variable()` 读值 + `showBattleResult` 状态
|
||||
- [x] `src/composables/useGameEngine.ts` — `sceneChange` 中检测 `scene.battleResult` 自动弹出
|
||||
- [x] `src/App.vue` — 整合 BattleHUD + BattleResult
|
||||
- [x] `src/locales/zh.json` + `en.json` — `continue` / `toMenu` i18n
|
||||
- [x] `public/scenes/demo.json` — `right_door` 场景添加 `battleHUD` 示例
|
||||
- [x] 验证:TypeScript + Vite build 通过
|
||||
|
||||
## 已完成
|
||||
|
||||
P0~P23 全部实现(除 P18)。详见 [CHANGELOG.md](CHANGELOG.md)。
|
||||
|
||||
Reference in New Issue
Block a user