562 lines
18 KiB
Markdown
562 lines
18 KiB
Markdown
# 声控狗叫对战 2D 浏览器游戏设计与实现计划
|
||
|
||
## 目标
|
||
|
||
基于用户提供的视频:
|
||
|
||
`C:\Users\DSK\Videos\一款双方比狗叫的游戏 - 1.一款双方比狗叫的游戏(Av116504192360177,P1).mp4`
|
||
|
||
提取其中“双方比狗叫”的核心玩法,并按照 BDD / TDD / DDD 的方法,为 Genarrative 中可运行于浏览器的 2D 游戏方案生成一份可落地设计与实现思路。实现方向遵循仓库内 `game-studio` 插件工作流,默认采用 2D Phaser + TypeScript + Vite + DOM HUD 的浏览器游戏架构。
|
||
|
||
本计划仅做方案设计,不直接编码。
|
||
|
||
## 当前上下文与输入分析
|
||
|
||
### 已识别视频核心画面
|
||
|
||
通过抽帧观察,视频中的游戏呈现出以下稳定特征:
|
||
|
||
- 画面是横版 2D 手绘舞台,场景包括公园、海边等固定关卡背景。
|
||
- 双方各有一只狗作为对战角色,站在左右两侧。
|
||
- 中央有明显倒计时,例如 `30`、`28`。
|
||
- 顶部有红蓝双方拉锯式能量条 / 进度条。
|
||
- 中央提示出现:`对着麦克风汪一声`、`用声音大小 + 叫声次数推动能量条!`
|
||
- 玩家输入不是传统键鼠,而是麦克风声音。
|
||
- 玩家需要模仿狗叫,系统根据声音大小与叫声次数推动能量条。
|
||
- 屏幕会根据叫声出现 `BARK`、`WOOF`、`WAN`、`WANGOOF` 等拟声词与冲击波视觉反馈。
|
||
- 回合结束时,根据能量条偏向或推进结果判定胜负。
|
||
|
||
### 提炼出的核心玩法
|
||
|
||
这是一个“声控拔河式狗叫对战”小游戏:
|
||
|
||
- 两名玩家 / 一名玩家对 AI 分别代表左右两只狗。
|
||
- 每局限时 30 秒。
|
||
- 玩家通过麦克风持续发出狗叫声。
|
||
- 游戏实时分析音量峰值、叫声次数、叫声节奏。
|
||
- 声音越大、叫声越密集,己方推动力越强。
|
||
- 顶部能量条在双方推动力差值下左右移动。
|
||
- 时间结束后,能量条偏向哪一方,哪一方获胜。
|
||
|
||
### 需要合理抽象的地方
|
||
|
||
视频中存在直播弹幕、贴图、表情包、遮挡层,这些不是游戏本体机制。本方案只吸收游戏本体核心:
|
||
|
||
- 双方狗狗对叫
|
||
- 麦克风输入
|
||
- 声音强度 + 次数判定
|
||
- 红蓝拉锯能量条
|
||
- 限时回合
|
||
- 夸张拟声词与冲击波反馈
|
||
|
||
## game-studio 插件路线
|
||
|
||
根据仓库内 `.hermes/plugins/game-studio` 技能:
|
||
|
||
- 早期游戏工作先走 `game-studio` 总入口。
|
||
- 2D 浏览器游戏默认选择 Phaser。
|
||
- 架构上需要分离 simulation 与 renderer。
|
||
- HUD / 菜单 / 设置优先使用 DOM overlay,不把密集文字塞进 canvas。
|
||
- 玩法状态不应由 Phaser Scene 直接持有,Scene 只负责渲染、动画、相机、输入适配。
|
||
|
||
因此本方案采用:
|
||
|
||
- Runtime:Phaser 3
|
||
- Language:TypeScript
|
||
- Build:Vite
|
||
- UI:React/DOM HUD overlay 或项目现有 DOM UI 层
|
||
- Audio input:Web Audio API + MediaDevices.getUserMedia
|
||
- Simulation:纯 TS domain/service 层
|
||
- Renderer:Phaser Scene 读取 simulation snapshot 并播放动画/特效
|
||
|
||
## 游戏概念设计
|
||
|
||
### 游戏名建议
|
||
|
||
- 中文:`汪汪声浪大作战`
|
||
- 英文代号:`bark-battle`
|
||
- Play type ID 建议:`bark-battle`
|
||
|
||
### 玩家幻想
|
||
|
||
玩家不是通过按键战斗,而是真的对着麦克风“汪汪叫”,把自己的狗狗声浪推向对手。游戏目标是在倒计时结束前用更响、更密集、更有节奏的叫声赢得声浪拔河。
|
||
|
||
### 核心动词
|
||
|
||
- 叫:对麦克风发出狗叫声。
|
||
- 推:通过叫声推动能量条。
|
||
- 压制:让能量条持续向对手方向倾斜。
|
||
- 爆发:短时间内连续高质量叫声触发冲击波。
|
||
- 防守:对手强势时通过持续叫声把能量条拉回。
|
||
|
||
### 单局流程
|
||
|
||
1. 准备阶段
|
||
- 展示双方狗狗、地图、麦克风权限提示。
|
||
- 用户授权麦克风。
|
||
- 系统检测环境噪音并校准阈值。
|
||
|
||
2. 倒计时阶段
|
||
- 3、2、1 或中央 `30` 倒计时开始。
|
||
- 玩家看到提示:`对着麦克风汪一声`。
|
||
|
||
3. 对战阶段
|
||
- 每帧或固定 tick 采集麦克风音量。
|
||
- 根据音量峰值与短促叫声次数计算本方 barkPower。
|
||
- AI 或远端对手产生 opponentPower。
|
||
- 能量条根据 `playerPower - opponentPower` 拉锯。
|
||
- 狗狗张嘴动画、拟声词、冲击波按声音强度生成。
|
||
|
||
4. 结算阶段
|
||
- 30 秒结束。
|
||
- 能量条偏玩家侧则胜利,偏对手侧则失败,接近中线则平局。
|
||
- 展示叫声次数、最大音量、平均节奏、声浪评分。
|
||
|
||
5. 重开 / 返回
|
||
- 支持再来一局。
|
||
- 支持返回玩法入口或结果页。
|
||
|
||
## 规则设计
|
||
|
||
### 关键状态
|
||
|
||
```ts
|
||
type BarkBattlePhase = 'permission' | 'calibration' | 'countdown' | 'playing' | 'finished'
|
||
|
||
type BarkBattleSnapshot = {
|
||
phase: BarkBattlePhase
|
||
remainingMs: number
|
||
energy: number // -100 到 100,负数偏对手,正数偏玩家
|
||
player: BarkSideState
|
||
opponent: BarkSideState
|
||
winner: 'player' | 'opponent' | 'draw' | null
|
||
}
|
||
|
||
type BarkSideState = {
|
||
barkCount: number
|
||
currentVolume: number
|
||
recentPeak: number
|
||
combo: number
|
||
power: number
|
||
isBarking: boolean
|
||
}
|
||
```
|
||
|
||
### 输入判定
|
||
|
||
#### 音量采样
|
||
|
||
- 使用 Web Audio API 创建 `AnalyserNode`。
|
||
- 每个 simulation tick 读取频域或时域数据。
|
||
- 计算 RMS 或 peak volume。
|
||
- 根据校准后的环境噪音设置动态阈值。
|
||
|
||
#### 一次“叫声”的判定
|
||
|
||
一次有效叫声建议满足:
|
||
|
||
- 音量超过 `barkThreshold`。
|
||
- 与上一次叫声峰值至少间隔 `minBarkGapMs`,避免持续噪音被无限计数。
|
||
- 持续时长在合理范围,例如 80ms 到 1200ms。
|
||
- 可选:频谱能量集中在中高频,不强制做复杂语音识别,MVP 先用音量 + 峰值节奏。
|
||
|
||
#### 推动力计算
|
||
|
||
```text
|
||
playerPower = volumeScore * 0.65 + barkRateScore * 0.35 + comboBonus
|
||
opponentPower = aiPower 或远端玩家 power
|
||
energyDelta = (playerPower - opponentPower) * deltaTime * balanceFactor
|
||
energy = clamp(energy + energyDelta, -100, 100)
|
||
```
|
||
|
||
### AI 对手 MVP
|
||
|
||
若先做单机浏览器版,右侧对手可由 AI 模拟:
|
||
|
||
- 简单难度:周期性小叫,power 低。
|
||
- 普通难度:有节奏地爆发,power 中等。
|
||
- 困难难度:根据玩家领先程度自适应追赶,但不得作弊到不可赢。
|
||
|
||
后续可扩展为多人实时对战。
|
||
|
||
## BDD 行为场景
|
||
|
||
### 功能: 麦克风授权与准备
|
||
|
||
```gherkin
|
||
功能: 狗叫对战麦克风准备
|
||
为了让玩家能用声音参与对战
|
||
作为浏览器玩家
|
||
我希望游戏在开局前明确请求麦克风权限并完成环境校准
|
||
|
||
场景: 玩家允许麦克风权限后进入准备倒计时
|
||
假如玩家打开狗叫对战页面
|
||
当玩家同意浏览器麦克风授权
|
||
那么系统应进入环境噪音校准阶段
|
||
而且校准完成后应显示开局倒计时
|
||
|
||
场景: 玩家拒绝麦克风权限
|
||
假如玩家打开狗叫对战页面
|
||
当玩家拒绝浏览器麦克风授权
|
||
那么系统应显示无法声控游玩的提示
|
||
而且应提供重试授权入口
|
||
而且不应直接开始对战
|
||
```
|
||
|
||
### 功能: 声音推动能量条
|
||
|
||
```gherkin
|
||
功能: 声音大小和叫声次数推动能量条
|
||
为了复刻双方比狗叫的核心体验
|
||
作为玩家
|
||
我希望自己的叫声能实时推动顶部能量条
|
||
|
||
场景: 玩家发出一次有效狗叫
|
||
假如游戏处于 playing 阶段
|
||
而且麦克风输入音量超过有效叫声阈值
|
||
当系统检测到一次新的叫声峰值
|
||
那么玩家叫声次数应增加 1
|
||
而且玩家狗狗应播放张嘴吠叫动画
|
||
而且画面应出现拟声词反馈
|
||
|
||
场景: 玩家连续大声狗叫压制对手
|
||
假如游戏处于 playing 阶段
|
||
而且玩家在短时间内产生多次有效叫声
|
||
当玩家推动力高于对手推动力
|
||
那么顶部能量条应向玩家侧移动
|
||
而且玩家侧声浪特效应增强
|
||
|
||
场景: 环境噪音低于阈值不计入叫声
|
||
假如游戏处于 playing 阶段
|
||
当麦克风只有低于阈值的背景噪音
|
||
那么玩家叫声次数不应增加
|
||
而且能量条不应因为背景噪音明显移动
|
||
```
|
||
|
||
### 功能: 限时胜负结算
|
||
|
||
```gherkin
|
||
功能: 狗叫对战胜负结算
|
||
为了让单局对抗有明确目标
|
||
作为玩家
|
||
我希望倒计时结束后根据能量条位置判定胜负
|
||
|
||
场景: 倒计时结束时玩家侧占优
|
||
假如游戏剩余时间归零
|
||
而且能量条位于玩家侧
|
||
当系统进入结算阶段
|
||
那么系统应判定玩家胜利
|
||
而且展示玩家叫声次数、最大音量和声浪评分
|
||
|
||
场景: 倒计时结束时双方接近平衡
|
||
假如游戏剩余时间归零
|
||
而且能量条处于平局阈值范围内
|
||
当系统进入结算阶段
|
||
那么系统应判定为平局
|
||
而且展示再来一局入口
|
||
```
|
||
|
||
### 功能: 移动端与无麦克风降级
|
||
|
||
```gherkin
|
||
功能: 声控游戏移动端与无麦克风降级
|
||
为了让不同设备玩家都能理解当前状态
|
||
作为移动端或无麦克风环境玩家
|
||
我希望系统给出清晰、可操作的降级路径
|
||
|
||
场景: 当前浏览器不支持麦克风 API
|
||
假如玩家设备不支持 getUserMedia
|
||
当玩家进入狗叫对战页面
|
||
那么系统应显示设备不支持麦克风输入
|
||
而且提供返回入口
|
||
|
||
场景: 移动端进入对战页面
|
||
假如玩家使用移动端浏览器
|
||
当玩家进入狗叫对战页面
|
||
那么主要能量条、倒计时和狗狗角色应保持可见
|
||
而且非关键设置应收起到菜单中
|
||
```
|
||
|
||
## DDD 领域划分
|
||
|
||
### 领域层:bark-battle domain
|
||
|
||
职责:只处理玩法规则,不依赖 Phaser、DOM、Web Audio、后端。
|
||
|
||
建议模块:
|
||
|
||
- `BarkBattleSession`
|
||
- 管理 phase、remainingMs、energy、winner。
|
||
- `BarkDetector`
|
||
- 根据音量样本判断是否形成一次有效叫声。
|
||
- `EnergyTugOfWar`
|
||
- 根据双方 power 更新能量条。
|
||
- `BarkBattleScoring`
|
||
- 计算最大音量、叫声次数、combo、评分。
|
||
- `OpponentStrategy`
|
||
- 单机 AI 对手策略接口。
|
||
|
||
领域规则必须可用纯单元测试验证。
|
||
|
||
### 应用层:use case / controller
|
||
|
||
职责:编排麦克风输入、simulation tick、AI 对手、结果输出。
|
||
|
||
建议用例:
|
||
|
||
- `requestMicrophonePermission()`
|
||
- `calibrateAmbientNoise()`
|
||
- `startBarkBattleSession()`
|
||
- `submitAudioSample(sample)`
|
||
- `tickBarkBattle(deltaMs)`
|
||
- `finishBarkBattle()`
|
||
|
||
### 基础设施层
|
||
|
||
职责:浏览器 API 与引擎适配。
|
||
|
||
- `BrowserMicrophoneInput`
|
||
- 封装 `navigator.mediaDevices.getUserMedia`。
|
||
- 输出 normalized volume samples。
|
||
- `PhaserBarkBattleScene`
|
||
- 渲染狗狗、背景、拟声词、冲击波。
|
||
- 不持有核心玩法规则。
|
||
- `DomBarkBattleHud`
|
||
- 展示倒计时、能量条、权限提示、结算面板。
|
||
|
||
### 表现层
|
||
|
||
- Phaser Canvas:地图、狗狗、声浪、粒子、拟声词。
|
||
- DOM HUD:顶部能量条、倒计时、权限/结算/设置面板。
|
||
|
||
## TDD 落地顺序
|
||
|
||
### 第一轮:领域规则 RED-GREEN-REFACTOR
|
||
|
||
先写纯 TS 单元测试,不接 Phaser,不接麦克风。
|
||
|
||
目标测试:
|
||
|
||
- `BarkDetector`:超过阈值且间隔足够时计为一次叫声。
|
||
- `BarkDetector`:持续噪音不会无限增加叫声次数。
|
||
- `EnergyTugOfWar`:玩家 power 高于对手时 energy 向玩家侧移动。
|
||
- `EnergyTugOfWar`:energy 被 clamp 在 -100 到 100。
|
||
- `BarkBattleSession`:倒计时归零后进入 finished。
|
||
- `BarkBattleSession`:根据 energy 判定 player/opponent/draw。
|
||
|
||
### 第二轮:应用层测试
|
||
|
||
- 模拟音频 sample 输入,验证 session snapshot 更新。
|
||
- 模拟 AI 对手 power,验证能量条拉锯。
|
||
- 模拟权限失败,验证 phase 不进入 playing。
|
||
|
||
### 第三轮:组件 / 集成测试
|
||
|
||
- HUD 根据 snapshot 显示倒计时。
|
||
- HUD 根据 energy 渲染红蓝能量条比例。
|
||
- 权限拒绝时显示重试入口。
|
||
- 结算阶段显示胜负与再来一局。
|
||
|
||
### 第四轮:浏览器 smoke / playtest
|
||
|
||
- 本地启动页面。
|
||
- 授权麦克风。
|
||
- 对麦克风发声后看到拟声词与能量条变化。
|
||
- 移动端宽度下主游戏画面不被 HUD 遮挡。
|
||
|
||
## 建议文件结构
|
||
|
||
如果作为独立前端玩法原型,可采用:
|
||
|
||
```text
|
||
src/games/bark-battle/
|
||
domain/
|
||
BarkBattleSession.ts
|
||
BarkDetector.ts
|
||
EnergyTugOfWar.ts
|
||
BarkBattleScoring.ts
|
||
OpponentStrategy.ts
|
||
application/
|
||
BarkBattleController.ts
|
||
BrowserMicrophoneInput.ts
|
||
phaser/
|
||
BarkBattleScene.ts
|
||
BarkBattlePreloadScene.ts
|
||
barkBattleAssets.ts
|
||
ui/
|
||
BarkBattleHud.tsx
|
||
BarkBattleResultPanel.tsx
|
||
BarkBattlePermissionPanel.tsx
|
||
tests/
|
||
BarkDetector.test.ts
|
||
EnergyTugOfWar.test.ts
|
||
BarkBattleSession.test.ts
|
||
```
|
||
|
||
如果接入 Genarrative 玩法类型闭环,后续还需要按 `genarrative-play-type-integration` 扩展:
|
||
|
||
```text
|
||
src/components/bark-battle-runtime/BarkBattleRuntimeShell.tsx
|
||
src/components/bark-battle-result/BarkBattleResultView.tsx
|
||
src/services/barkBattleRuntimeClient.ts
|
||
packages/shared/src/contracts/barkBattle.ts
|
||
server-rs/crates/shared-contracts/src/bark_battle.rs
|
||
```
|
||
|
||
MVP 阶段建议先做浏览器单机 runtime 原型,再决定是否进入创作入口、作品发布、广场和后端持久化。
|
||
|
||
## UI / 视觉方向
|
||
|
||
### 画面
|
||
|
||
- 横版固定舞台。
|
||
- 左右两只狗对峙。
|
||
- 背景可先做公园一张图,后续扩展海边、街区等地图。
|
||
- 狗狗用 2D sprite 或简单骨架帧动画。
|
||
|
||
### HUD
|
||
|
||
- 顶部:红蓝声浪能量条。
|
||
- 中央:大号倒计时,只在开局和关键时间突出显示。
|
||
- 左右:双方狗狗状态,不堆叠复杂面板。
|
||
- 底部或角落:麦克风状态、小型重试按钮。
|
||
- 结算:居中弹出简洁面板,显示胜负和关键数据。
|
||
|
||
### 动效
|
||
|
||
- 叫声触发狗狗张嘴。
|
||
- 声音越大,拟声词越大,冲击波越宽。
|
||
- combo 时触发短暂屏幕震动,但不能遮挡能量条。
|
||
- 尊重 reduced motion,非必要动画可降级。
|
||
|
||
## 测试映射
|
||
|
||
| BDD 场景 | 测试层级 | 目标文件 | 状态 |
|
||
| --- | --- | --- | --- |
|
||
| 玩家允许麦克风权限后进入准备倒计时 | application/component | `BarkBattleController.test.ts`, `BarkBattlePermissionPanel.test.tsx` | planned |
|
||
| 玩家拒绝麦克风权限 | application/component | `BarkBattleController.test.ts`, `BarkBattlePermissionPanel.test.tsx` | planned |
|
||
| 玩家发出一次有效狗叫 | unit | `BarkDetector.test.ts` | planned |
|
||
| 玩家连续大声狗叫压制对手 | unit/integration | `EnergyTugOfWar.test.ts`, `BarkBattleController.test.ts` | planned |
|
||
| 环境噪音低于阈值不计入叫声 | unit | `BarkDetector.test.ts` | planned |
|
||
| 倒计时结束时玩家侧占优 | unit | `BarkBattleSession.test.ts` | planned |
|
||
| 倒计时结束时双方接近平衡 | unit | `BarkBattleSession.test.ts` | planned |
|
||
| 当前浏览器不支持麦克风 API | component | `BarkBattlePermissionPanel.test.tsx` | planned |
|
||
| 移动端进入对战页面 | visual/smoke | Playwright 或人工 playtest 清单 | planned |
|
||
|
||
## 验证命令建议
|
||
|
||
具体命令以后续实际落地位置为准,建议包括:
|
||
|
||
```bash
|
||
npm run test -- --run src/games/bark-battle/**/*.test.ts
|
||
npm run test -- --run src/games/bark-battle/**/*.test.tsx
|
||
npm run typecheck
|
||
npm run check:encoding
|
||
```
|
||
|
||
若接入 Genarrative 后端或玩法配置,还需要追加:
|
||
|
||
```bash
|
||
cd server-rs && cargo check -p api-server -p shared-contracts --no-default-features
|
||
npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts
|
||
```
|
||
|
||
## 实施阶段拆分
|
||
|
||
### Phase 0:产品与技术定稿
|
||
|
||
- 确认玩法 ID:`bark-battle`。
|
||
- 确认 MVP 只做单机玩家 vs AI,不做实时多人。
|
||
- 确认是否只做 runtime 原型,还是接入 Genarrative 创作入口。
|
||
- 确认是否允许浏览器麦克风权限作为核心输入。
|
||
|
||
### Phase 1:纯领域模型
|
||
|
||
- 建立 bark-battle domain。
|
||
- 按 TDD 写 `BarkDetector`、`EnergyTugOfWar`、`BarkBattleSession` 测试。
|
||
- 实现最小规则让测试通过。
|
||
|
||
### Phase 2:麦克风输入适配
|
||
|
||
- 封装 Web Audio API。
|
||
- 支持权限请求、权限失败、环境噪音校准。
|
||
- 使用 mock input 完成自动化测试,真实麦克风做 smoke。
|
||
|
||
### Phase 3:Phaser 2D runtime
|
||
|
||
- 新建 Phaser Scene。
|
||
- 绘制或占位加载公园背景、左右狗狗、声浪特效。
|
||
- Scene 只消费 snapshot,不写规则。
|
||
- 接入 DOM HUD。
|
||
|
||
### Phase 4:反馈与结算
|
||
|
||
- 加入拟声词、冲击波、狗狗张嘴动画。
|
||
- 加入结算面板。
|
||
- 加入再来一局与返回入口。
|
||
|
||
### Phase 5:Genarrative 集成可选项
|
||
|
||
若要正式接入玩法类型:
|
||
|
||
- 补 `shared-contracts` 中 bark-battle runtime/result DTO。
|
||
- 补前端 service 与 runtime shell。
|
||
- 补入口配置数据库 seed。
|
||
- 补作品架 / 发布 / 广场链路,若需要持久化成绩或作品。
|
||
- 按 `genarrative-play-type-integration` 执行完整闭环验证。
|
||
|
||
## 风险与权衡
|
||
|
||
### 麦克风权限风险
|
||
|
||
浏览器麦克风权限受 HTTPS、浏览器策略、用户设置影响。MVP 需要明确:
|
||
|
||
- 本地开发可在 localhost 使用。
|
||
- 线上必须 HTTPS。
|
||
- 权限拒绝需要可恢复。
|
||
|
||
### 声音识别准确性风险
|
||
|
||
MVP 不建议做复杂“是否真的是狗叫”的 AI 识别,否则实现成本高、误判多。建议先用:
|
||
|
||
- 音量阈值
|
||
- 峰值次数
|
||
- 节奏间隔
|
||
- 环境噪音校准
|
||
|
||
后续再考虑加入频谱特征或 ML 分类。
|
||
|
||
### 噪音作弊风险
|
||
|
||
玩家可以喊叫、拍桌子或播放音频。若是娱乐派对玩法可以接受;若要竞技公平,需要后续加入:
|
||
|
||
- 频谱特征
|
||
- 输入冷却
|
||
- 异常持续噪音削弱
|
||
- 本地/服务端反作弊策略
|
||
|
||
### 移动端兼容风险
|
||
|
||
移动端 Web Audio 可能需要用户手势激活 AudioContext。计划中需把“开始”按钮作为显式用户手势,避免自动启动失败。
|
||
|
||
### UI 遮挡风险
|
||
|
||
视频原型中的核心可读信息非常少:倒计时、能量条、狗狗、拟声词。实现时应避免把说明文案、复杂面板长期铺在画面上。
|
||
|
||
## 开放问题
|
||
|
||
1. MVP 是“玩家 vs AI”,还是需要从第一版开始支持双人同屏 / 联机?
|
||
2. 是否要作为 Genarrative 新玩法入口完整接入,还是先做独立 runtime 原型?
|
||
3. 是否需要记录成绩、发布作品、进入作品架和广场?
|
||
4. 狗狗与背景素材是使用临时占位、AI 生成,还是需要复用项目既有素材系统?
|
||
5. 是否允许游戏强依赖麦克风权限,还是必须提供键盘备用输入?
|
||
|
||
## 推荐下一步
|
||
|
||
建议下一步先执行 Phase 0 + Phase 1:
|
||
|
||
1. 明确 MVP 边界:单机玩家 vs AI。
|
||
2. 写 `BarkDetector` / `EnergyTugOfWar` / `BarkBattleSession` 的 BDD 对应单元测试。
|
||
3. 不接 Phaser、不接麦克风,先把核心规则用 TDD 跑通。
|
||
4. 规则稳定后再接 Web Audio 与 Phaser runtime。
|