feat: electron desktop packaging, CDN asset migration, production docs, scene JSON spec

This commit is contained in:
2026-06-09 23:20:27 +08:00
parent 48fb89449a
commit 3a7dd2f405
35 changed files with 900 additions and 135 deletions

169
README.md
View File

@@ -1,142 +1,115 @@
# 交互式电影游戏引擎
基于 Vue 3 + TypeScript 的浏览器端交互式电影游戏引擎。
克隆项目 → 放视频 → 写 JSON → 打包上线。
## 快速开始
```bash
git clone <repo-url> mygame
cd mygame
npm install
npm run dev
```
浏览器打开 `http://localhost:5173/` 即可体验示例剧情
浏览器打开 `http://localhost:5173/` 预览示例游戏
打开 `http://localhost:5173/editor/` 使用可视化编辑器。
## 如何使用
## 制作你的游戏
### 1. 编写剧情 JSON
### 1. 放视频
`public/scenes/` 目录下创建 JSON 文件,定义你的场景和分支:
把你的视频文件放到 `public/videos/` 目录。推荐 MP4 (H.264)1280×7202-5Mbps。
### 2. 编写剧情 JSON
编辑 `public/scenes/demo.json`(或创建新 JSON 文件,修改 `src/App.vue` 中的加载路径)。
```json
{
"startScene": "scene_1",
"variables": {
"trust": 50,
"courage": 0
},
"startScene": "intro",
"variables": { "trust": 50 },
"scenes": {
"scene_1": {
"id": "scene_1",
"videoUrl": "/videos/scene_1.mp4",
"intro": {
"id": "intro",
"videoUrl": "/videos/intro.mp4",
"choices": [
{
"text": "打开左边的门",
"targetScene": "scene_2a",
"effects": [
{ "type": "add", "target": "courage", "value": 10 }
]
},
{
"text": "打开右边的门",
"targetScene": "scene_2b"
}
{ "text": "帮助他", "targetScene": "help_end" },
{ "text": "离开", "targetScene": "leave_end" }
]
},
"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": []
}
"help_end": { "id": "help_end", "videoUrl": "/videos/help.mp4", "choices": [] },
"leave_end": { "id": "leave_end", "videoUrl": "/videos/leave.mp4", "choices": [] }
}
}
```
**字段说明:**
这 15 行 JSON 就是一个完整可玩游戏。
| 字段 | 说明 |
|------|------|
| `startScene` | 游戏开始的场景 ID |
| `variables` | 全局变量初始值(如好感度、勇气值) |
| `scenes` | 所有场景节点key 为场景 ID |
| `videoUrl` | 视频文件路径,放在 `public/videos/` 下 |
| `choices` | 选项列表,为空或不存在时视为结局 |
| `nextScene` | 没有选项时的默认下一场景(自动跳转) |
| `effects` | 选择后的效果,类型: `set`/`add`/`toggleFlag` |
| `conditions` | 选项的显示条件(`==`, `!=`, `>`, `<`, `>=`, `<=`, `hasFlag` |
### 3. 完整字段参考
### 2. 放置视频文件
详见 [场景 JSON 规范文档](docs/SCENE_JSON_SPEC.md)。引擎支持:
将视频文件放入 `public/videos/` 目录,推荐 MP4 (H.264) 格式。
- 分支叙事 / 条件分支 / QTE 快速反应事件 / 循环等待
- 独立 BGM + Ducking / 跳过已看 + 倍速 / 章节选择
- 成就系统 / 结局画廊 / 章节回顾 / 字幕多语言
- 关键选择提示 / 键盘全导航 / 可访问性设置
- 图片/视频热点交互 / 全屏模式
生成测试视频(需要 ffmpeg
### 4. 预览和调试
```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
npm run dev # Vite 实时预览,改代码自动刷新
```
### 3. 修改加载的剧情文件
### 5. 打包上线
`src/App.vue` 中修改 `loadGame()` 的路径:
```ts
await loadGame('/scenes/your_story.json')
```bash
npm run pack:html # Web 版 → release/mygame.zip上传 itch.io
npm run pack:mac # macOS → release/MyGame-darwin-*/
npm run pack:win # Windows → release/MyGame-win32-x64/
```
Web 版上传 itch.io 选 "HTML" 类型。桌面版为可运行文件夹,双击即用。
## 自定义 UI
引擎的 UI 组件在 `src/components/` 目录中,可自由修改 Vue 组件、CSS 样式。
引擎核心 `engine/` 目录也可修改。
## 目录结构
```
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
mygame/
├── engine/ # 核心引擎(可自由修改
├── src/ # Vue UI 组件(可自由修改)
│ ├── components/ # GamePlayer、ChoicePanel 等
│ ├── composables/ # 桥接引擎 ↔ UI
│ ├── stores/ # Pinia 状态
├── locales/ # 多语言翻译
│ └── App.vue # 入口组件
├── editor/ # 可视化剧情编辑
├── public/
│ ├── scenes/demo.json # 示例剧情
── videos/ # 视频资源
├── ROADMAP.md # 开发路线
│ ├── videos/ # 放你的视频
── audio/ # 放你的 BGM
│ ├── images/ # 放缩略图、热点
│ ├── subtitles/ # 放字幕 .vtt
│ └── scenes/
│ └── demo.json # 你的剧情定义 ← 主要编辑这个
├── electron/ # 桌面打包配置
├── docs/ # JSON 规范文档
├── scripts/ # 打包脚本
└── 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也能简化引擎的逻辑。
| 参数 | 建议值 |
|------|--------|
| 格式 | MP4 (H.264) |
| 分辨率 | 1280×720 或 1920×1080 |
| 帧率 | 25fps 或 30fps |
| 码率 | 2-5 Mbps |
| 循环段 | 正文段 + 循环段合成为一个文件,用 `loopStart`/`loopEnd` 标记区间 |
| 背景音乐 | 不要在视频中嵌入 BGM用独立 .mp3 + `bgmUrl` 字段 |
| 字幕 | WebVTT 格式(.vtt时间轴精确到毫秒 |