142 lines
3.8 KiB
Markdown
142 lines
3.8 KiB
Markdown
# 交互式电影游戏引擎
|
||
|
||
基于 Vue 3 + TypeScript 的浏览器端交互式电影游戏引擎。
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
浏览器打开 `http://localhost:5173/` 即可体验示例剧情。
|
||
|
||
## 如何使用
|
||
|
||
### 1. 编写剧情 JSON
|
||
|
||
在 `public/scenes/` 目录下创建 JSON 文件,定义你的场景和分支:
|
||
|
||
```json
|
||
{
|
||
"startScene": "scene_1",
|
||
"variables": {
|
||
"trust": 50,
|
||
"courage": 0
|
||
},
|
||
"scenes": {
|
||
"scene_1": {
|
||
"id": "scene_1",
|
||
"videoUrl": "/videos/scene_1.mp4",
|
||
"choices": [
|
||
{
|
||
"text": "打开左边的门",
|
||
"targetScene": "scene_2a",
|
||
"effects": [
|
||
{ "type": "add", "target": "courage", "value": 10 }
|
||
]
|
||
},
|
||
{
|
||
"text": "打开右边的门",
|
||
"targetScene": "scene_2b"
|
||
}
|
||
]
|
||
},
|
||
"scene_2a": {
|
||
"id": "scene_2a",
|
||
"videoUrl": "/videos/scene_2a.mp4",
|
||
"nextScene": "ending"
|
||
},
|
||
"scene_2b": {
|
||
"id": "scene_2b",
|
||
"videoUrl": "/videos/scene_2b.mp4",
|
||
"choices": []
|
||
},
|
||
"ending": {
|
||
"id": "ending",
|
||
"videoUrl": "/videos/ending.mp4",
|
||
"choices": []
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**字段说明:**
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `startScene` | 游戏开始的场景 ID |
|
||
| `variables` | 全局变量初始值(如好感度、勇气值) |
|
||
| `scenes` | 所有场景节点,key 为场景 ID |
|
||
| `videoUrl` | 视频文件路径,放在 `public/videos/` 下 |
|
||
| `choices` | 选项列表,为空或不存在时视为结局 |
|
||
| `nextScene` | 没有选项时的默认下一场景(自动跳转) |
|
||
| `effects` | 选择后的效果,类型: `set`/`add`/`toggleFlag` |
|
||
| `conditions` | 选项的显示条件(`==`, `!=`, `>`, `<`, `>=`, `<=`, `hasFlag`) |
|
||
|
||
### 2. 放置视频文件
|
||
|
||
将视频文件放入 `public/videos/` 目录,推荐 MP4 (H.264) 格式。
|
||
|
||
生成测试视频(需要 ffmpeg):
|
||
|
||
```bash
|
||
ffmpeg -f lavfi -i "color=c=0x1a1a2e:s=1280x720:d=3" \
|
||
-vf "drawtext=text='章节标题':fontcolor=white:fontsize=32:x=(w-text_w)/2:y=(h-text_h)/2" \
|
||
public/videos/scene_1.mp4
|
||
```
|
||
|
||
### 3. 修改加载的剧情文件
|
||
|
||
在 `src/App.vue` 中修改 `loadGame()` 的路径:
|
||
|
||
```ts
|
||
await loadGame('/scenes/your_story.json')
|
||
```
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
moviegame/
|
||
├── engine/ # 框架无关的核心引擎(不依赖 Vue)
|
||
│ ├── core/
|
||
│ │ ├── Engine.ts # 主循环
|
||
│ │ ├── SceneManager.ts # 场景管理
|
||
│ │ ├── VideoManager.ts # 视频播放控制
|
||
│ │ └── StateManager.ts # 状态/变量/条件系统
|
||
│ └── types.ts # 类型定义
|
||
├── src/ # Vue 播放器
|
||
│ ├── components/
|
||
│ │ ├── GamePlayer.vue # 视频播放器
|
||
│ │ └── ChoicePanel.vue # 选项面板
|
||
│ ├── composables/
|
||
│ │ └── useGameEngine.ts # 引擎 ↔ Vue 桥接
|
||
│ ├── stores/
|
||
│ │ └── gameStore.ts # Pinia 状态
|
||
│ ├── App.vue
|
||
│ └── main.ts
|
||
├── public/
|
||
│ ├── scenes/demo.json # 示例剧情
|
||
│ └── videos/ # 视频资源
|
||
├── ROADMAP.md # 开发路线图
|
||
└── package.json
|
||
```
|
||
|
||
## 当前状态
|
||
|
||
**已完成 (P0 MVP):** 单视频播放 + 选项分支 + 状态系统 + JSON 驱动
|
||
|
||
**下一步 (P1):** A/B 双缓冲无缝切换、条件分支、IndexedDB 存档系统
|
||
|
||
详见 [ROADMAP.md](ROADMAP.md)。
|
||
|
||
## 命令
|
||
|
||
```bash
|
||
npm run dev # 启动开发服务器
|
||
npm run build # 构建生产版本
|
||
npm run preview # 预览构建结果
|
||
```
|
||
|
||
## 使用提示
|
||
场景虽然支持图片,但是图片场景容易触发一些bug,所以建议只使用视频场景,这样可以避免遇到没有测试覆盖的bug,也能简化引擎的逻辑。 |