diff --git a/editor/README.md b/editor/README.md new file mode 100644 index 0000000..a2dacde --- /dev/null +++ b/editor/README.md @@ -0,0 +1,114 @@ +# 剧情编辑器 + +基于 Vue Flow 的可视化交互式电影剧情编辑工具,通过拖拽节点和连线来编排游戏场景和分支。 + +## 启动 + +```bash +npm install +npm run dev +``` + +浏览器打开 `http://localhost:5173/editor/` + +## 界面布局 + +``` +┌──────────────────────────────────────────────────┐ +│ 工具栏: 新建 / 导入导出 / 加载示例 / 起始场景 │ +├────────────────────┬──────────────┬───────────────┤ +│ │ │ │ +│ 场景节点图 │ 属性编辑面板 │ 视频预览 │ +│ (Vue Flow) │ │ │ +│ │ │ │ +└────────────────────┴──────────────┴───────────────┘ +``` + +## 基本操作 + +### 场景节点图(左侧) + +- **点击节点** → 右侧面板打开该场景的属性编辑器 +- **拖拽节点端口到另一个节点** → 创建"选项"连线(自动生成选项文本) +- **缩放/平移**:鼠标滚轮缩放,拖拽画布平移 + +### 新建场景 + +点击工具栏 `+ 新场景`,生成一个新节点并自动选中。 + +### 编辑场景(右侧面板选中节点后) + +| 字段 | 说明 | +|------|------| +| 视频路径 | 该场景对应的视频文件,如 `/videos/scene_1.mp4` | +| 字幕路径 | 可选 WebVTT 字幕文件,如 `/subtitles/scene_1.vtt` | +| 默认下一场景 | 没有选项或选项超时后的自动跳转目标 | +| QTE | 快速反应事件:触发时间、提示文字、按键、限时、成功/失败跳转 | +| 选项列表 | 玩家可见的分支选项,包含文字、目标场景、限时 | + +### 选项管理 + +- 点击 `+ 添加选项` 增加新选项 +- 填写选项文字和目标场景 +- 可设置限时(秒),超时自动选第一项 +- 点 × 删除选项 + +### 删除场景 + +编辑器面板标题栏点击 🗑 按钮,会同时清理其他场景中指向该场景的引用。 + +## 数据管理 + +### 加载示例 + +点击 `加载示例` 载入 `public/scenes/demo.json`,了解数据格式。 + +### 导入 / 导出 JSON + +- **导出**:将当前编辑的剧情导出为 JSON 文件 +- **导入**:从 JSON 文件加载剧情数据 + +JSON 格式与游戏引擎的数据结构一致: + +```json +{ + "startScene": "scene_1", + "variables": {}, + "scenes": { + "scene_1": { + "id": "scene_1", + "videoUrl": "/videos/scene_1.mp4", + "choices": [ + { "text": "进入房间", "targetScene": "scene_2" } + ], + "nextScene": "", + "subtitleUrl": "", + "onEnter": [] + } + } +} +``` + +导出的 JSON 可直接放入 `public/scenes/` 目录供游戏引擎加载。 + +## 场景数据结构 + +```ts +interface SceneNode { + id: string // 唯一标识 + videoUrl: string // 视频文件路径 + subtitleUrl?: string // 字幕文件路径(可选) + choices?: Choice[] // 选项列表 + qte?: QTEDefinition // QTE 快速反应事件(可选) + nextScene?: string // 默认跳转场景 + onEnter?: Effect[] // 进入场景时触发的效果 +} + +interface Choice { + text: string // 选项文字 + targetScene: string // 目标场景 ID + conditions?: Condition[] // 显示条件(可选) + effects?: Effect[] // 触发效果(可选) + timeLimit?: number // 限时秒数,0=不限 +} +```