From 4f2c1a63a590af25cf46f60c418d16d4bf20908a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=8C?= <259278618@qq.com> Date: Thu, 13 Aug 2026 15:32:56 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=95=85=E4=BA=8B=E5=89=A7=E5=9C=BA?= =?UTF-8?q?=E5=8C=96=E5=AE=9E=E7=8E=B0=E8=AE=A1=E5=88=92=EF=BC=88Task=201-?= =?UTF-8?q?6=EF=BC=9Atheater.js/ActionCard/SceneTheater/play+result=20?= =?UTF-8?q?=E9=9B=86=E6=88=90/=E6=96=87=E6=A1=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/2026-08-13-story-theater.md | 758 ++++++++++++++++++ 1 file changed, 758 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-13-story-theater.md diff --git a/docs/superpowers/plans/2026-08-13-story-theater.md b/docs/superpowers/plans/2026-08-13-story-theater.md new file mode 100644 index 0000000..10b2cd8 --- /dev/null +++ b/docs/superpowers/plans/2026-08-13-story-theater.md @@ -0,0 +1,758 @@ +# 故事剧场化实现计划(三幕演出 + 动作卡全互动呈现) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 把每关从"文字问答"升级为"儿童小剧场":开场演出(旁白+字幕淡入+角色道具入场)、决策动作卡(替代文字选项列表)、分支演出(选择后动画过渡)、结局演出(庆祝/鼓励动画),决策树数据模型零改动。 + +**Architecture:** 纯前端呈现层升级。新增 `theater.js`(互动形态判定 + 演出数据提取纯函数)、`ActionCard.vue`(动作卡)、`SceneTheater.vue`(开场演出覆盖层);改造 `play.vue`(开场集成 + 动作卡 + 分支演出)与 `result.vue`(结局演出)。触控互动(PropPick 等 5 种)仅用于已有 config 互动节点;普通决策节点一律用动作卡呈现(**计划级修正**,见下)。全部 CSS 动画,无新依赖。 + +**Tech Stack:** uni-app (Vue 3) H5 先行、现有 RubyText/SpeakButton/speech.js/visual.js/sound.js、CSS keyframes。 + +**对规格的修正(重要)**:spec 中"按选项内容特征自动判定互动形态 a-e"与现有交互协议冲突——触控互动组件只有 success/fail 双出口(提交 options[0]/options[1]),而普通决策节点的 2-4 个选项各自指向独立分支,前端无法静态判定"最佳选项"。修正:普通决策节点(interaction_type=1)一律渲染动作卡(多分支语义完整保留),触控互动仅用于 config 非空的互动节点。全 36 关文字选项列表消灭的目标不变(动作卡兜底所有普通节点)。 + +--- + +### Task 1: `ui-src/src/utils/theater.js`(互动判定 + 演出数据提取) + +**Files:** +- Create: `ui-src/src/utils/theater.js` + +- [ ] **Step 1: 写文件** + +```js +// 剧场化工具:互动形态判定 + 开场演出数据提取(决策树模型零改动) + +const INTERACTION_MAP = { 2: 'PropPick', 3: 'StepSort', 5: 'DragPlace', 7: 'FindSpot', 8: 'LinkMatch' } + +// 互动形态判定:config 互动节点 → 对应触控组件;普通决策节点 → 动作卡 +// (触控组件只有 success/fail 双出口,普通节点多分支选项语义由 ActionCard 完整保留) +export function pickInteraction(node) { + if (node && node.config && INTERACTION_MAP[node.interaction_type]) { + return INTERACTION_MAP[node.interaction_type] + } + return 'ActionCard' +} + +// 开场演出道具:入口节点选项的道具名去重,最多 4 个 +export function entryProps(entry) { + const names = [] + for (const o of (entry && entry.options) || []) { + if (o.prop && o.prop.name && !names.includes(o.prop.name)) { + names.push(o.prop.name) + if (names.length >= 4) break + } + } + return names +} + +// 开场演出角色:入口节点人物(可能为空) +export function entryCharacter(entry) { + return entry && entry.character ? entry.character : null +} +``` + +- [ ] **Step 2: H5 编译检查** + +Run: `curl -s -o /dev/null -w "%{http_code}" http://localhost:5173/src/utils/theater.js` 返回 200。 + +- [ ] **Step 3: 提交** + +```bash +git add ui-src/src/utils/theater.js +git commit -m "feat: 剧场化工具 theater.js(互动形态判定 + 开场演出数据提取)" +``` + +--- + +### Task 2: `ui-src/src/components/ActionCard.vue`(动作卡组件) + +**Files:** +- Create: `ui-src/src/components/ActionCard.vue` + +动作卡 = 现有选项列表的升级呈现:每选项一张卡(序号徽章 + 道具图标/emoji + 短语拼音注音 + 听一听 + 按压弹跳 + c1-c4 四色边框)。 + +- [ ] **Step 1: 写组件** + +```vue + + + + + +``` + +- [ ] **Step 2: H5 编译检查** + +Run: `curl -s -o /dev/null -w "%{http_code}" http://localhost:5173/src/components/ActionCard.vue` 返回 200。 + +- [ ] **Step 3: 提交** + +```bash +git add ui-src/src/components/ActionCard.vue +git commit -m "feat: 动作卡组件 ActionCard(选项图标/拼音/听读/按压动画/四色边框)" +``` + +--- + +### Task 3: `ui-src/src/components/SceneTheater.vue`(开场演出覆盖层) + +**Files:** +- Create: `ui-src/src/components/SceneTheater.vue` + +开场演出:场景横幅 + 角色滑入 + 道具飞入 + 旁白自动朗读 + 字幕逐字淡入 + 跳过按钮。演出播完(或点跳过)后 emit done,父组件隐藏本层。 + +- [ ] **Step 1: 写组件** + +```vue + + + + + +``` + +- [ ] **Step 2: H5 编译检查** + +Run: `curl -s -o /dev/null -w "%{http_code}" http://localhost:5173/src/components/SceneTheater.vue` 返回 200。 + +- [ ] **Step 3: 提交** + +```bash +git add ui-src/src/components/SceneTheater.vue +git commit -m "feat: 开场演出组件 SceneTheater(旁白朗读+字幕逐字淡入+角色入场+道具飞入+跳过)" +``` + +--- + +### Task 4: `play.vue` 集成(开场演出 + 动作卡 + 分支演出) + +**Files:** +- Modify: `ui-src/src/pages/play/play.vue` + +- [ ] **Step 1: script 部分改造** + +` +``` + +- [ ] **Step 2: template 部分改造** + +在 `` 之前插入开场演出覆盖层,并把选项列表块替换为 ActionCard: + +开场覆盖层(插在 ``(topbar 结束)之后、`` 之前): + +```html + + +``` + +场景卡片加演出状态类(`.scene-card` 增加 `:class="{ 'fx-shake': sceneFx }"`): + +```html + +``` + +互动分发整块替换(原「互动组件(触控 5 种)」v-if 链 + 「选项选择(type 1)」v-else-if 的 `class="options"` 列表 + 「soon 兜底」三段,替换为 activeInteraction 驱动): + +```html + + + + + + + + + + 该互动玩法(类型 {{ curNode.interaction_type }})敬请期待 +``` + +- [ ] **Step 3: style 部分追加** + +在 `