Browse Source
Capture gameplay rules, seed-driven generation constraints, difficulty behavior, and UI flow for the new hex-grid chase mode before implementation. Made-with: Cursormaster
1 changed files with 218 additions and 0 deletions
@ -0,0 +1,218 @@ |
|||||
|
# 六边形追击游戏设计文档 |
||||
|
|
||||
|
## 1. 背景与目标 |
||||
|
|
||||
|
本设计用于在现有 Pixi 项目中实现一个单局时长较短、可重复游玩的回合制追击玩法: |
||||
|
|
||||
|
- 地图由六边形节点和连线组成; |
||||
|
- 玩家操控小偷每回合移动一步到相邻格; |
||||
|
- 小偷行动后官兵逼近一步; |
||||
|
- 到达出口即胜利,被抓住或无路可走即失败; |
||||
|
- 地图、出口、初始位置由 seed 驱动随机生成; |
||||
|
- 必须保证“存在可逃脱可能”,但不能过于简单; |
||||
|
- 左上角显示成功次数; |
||||
|
- 胜利后“重新开始”开新局;失败后“重试”重开当前局,“新一局”开新局。 |
||||
|
|
||||
|
## 2. 需求边界与约束 |
||||
|
|
||||
|
### 2.1 已确认交互决策 |
||||
|
|
||||
|
- 小偷移动方式:点击相邻六边形(纯点击)。 |
||||
|
- 官兵策略:支持难度配置(简单 / 普通 / 困难)。 |
||||
|
- 失败判定:同格失败 + 下一步无路可走失败。 |
||||
|
- 地图规模:小图,约 20~30 节点。 |
||||
|
- seed 方式:默认随机 + 支持手动输入。 |
||||
|
- 难度选择时机:开局前选择,本局固定。 |
||||
|
|
||||
|
### 2.2 非目标(本期不做) |
||||
|
|
||||
|
- 联网排行、存档系统、道具系统; |
||||
|
- 多官兵、多出口、迷雾视野; |
||||
|
- 复杂动画编排与特效系统化封装。 |
||||
|
|
||||
|
## 3. 总体架构 |
||||
|
|
||||
|
新增主玩法场景 `page_chase.ts`,从 `init` 进入。场景内部采用“模型与渲染分离”: |
||||
|
|
||||
|
- `GameModel`(纯逻辑层) |
||||
|
- 管理地图、seed、回合、角色位置、胜负状态; |
||||
|
- 负责生成校验(可逃脱且不简单); |
||||
|
- 对外暴露纯数据状态与动作接口。 |
||||
|
- `GameView`(展示与交互层) |
||||
|
- 渲染六边形节点、连线、角色标记、出口; |
||||
|
- 管理顶部 HUD、开局面板、结算弹层; |
||||
|
- 将点击行为转换为 `GameModel` 动作并刷新画面。 |
||||
|
|
||||
|
该拆分保证: |
||||
|
|
||||
|
- “重试同局”可通过快照精确恢复; |
||||
|
- seed 逻辑可单测; |
||||
|
- UI 调整不影响核心规则。 |
||||
|
|
||||
|
## 4. 数据模型 |
||||
|
|
||||
|
### 4.1 核心类型 |
||||
|
|
||||
|
- `NodeId: string` |
||||
|
- `GraphNode { id, q, r, neighbors: NodeId[] }` |
||||
|
- `GameGraph { nodes: Map<NodeId, GraphNode>, edgeList: [NodeId, NodeId][] }` |
||||
|
- `Difficulty = "easy" | "normal" | "hard"` |
||||
|
- `GameStatus = "setup" | "playing" | "win" | "lose"` |
||||
|
- `RoundSnapshot` |
||||
|
- `seed` |
||||
|
- `difficulty` |
||||
|
- `graph` |
||||
|
- `thiefStartNodeId` |
||||
|
- `guardStartNodeId` |
||||
|
- `exitNodeId` |
||||
|
- `thiefNodeId` |
||||
|
- `guardNodeId` |
||||
|
- `status` |
||||
|
|
||||
|
### 4.2 会话状态 |
||||
|
|
||||
|
- `winCount: number`(会话累计,场景生命周期内保留) |
||||
|
- `currentSeed: number` |
||||
|
- `currentSnapshot: RoundSnapshot | null`(失败后“重试”回放源) |
||||
|
|
||||
|
## 5. 地图生成与 seed 方案 |
||||
|
|
||||
|
### 5.1 RNG |
||||
|
|
||||
|
实现确定性 RNG(如 `mulberry32`): |
||||
|
|
||||
|
- 输入:32 位整数 seed; |
||||
|
- 输出:稳定伪随机序列; |
||||
|
- 任意同 seed + 同配置,生成结果一致。 |
||||
|
|
||||
|
### 5.2 六边形图构造 |
||||
|
|
||||
|
1. 使用轴坐标 `(q, r)` 作为节点坐标; |
||||
|
2. 依据小图配置随机生成 20~30 个节点; |
||||
|
3. 先构建连通骨架(类似生成树)确保全图可达; |
||||
|
4. 再按概率补少量边形成分叉路径,避免过线性。 |
||||
|
|
||||
|
### 5.3 出口与初始点放置 |
||||
|
|
||||
|
- `exit`:优先从边缘节点集合选取; |
||||
|
- `thiefStart`:到出口最短路距离至少 `minEscapeDist = 4`; |
||||
|
- `guardStart`:与小偷初始距离至少 `minInitialGap = 3`,并避免过近出口。 |
||||
|
|
||||
|
## 5.4 可玩性校验(硬约束) |
||||
|
|
||||
|
生成后执行验证,不满足则内部重采样(可通过 seed 偏移重试): |
||||
|
|
||||
|
1. **可逃脱性**:存在至少一条小偷策略可在有限步内到达出口; |
||||
|
2. **非过简性**:不能出现“几乎无脑 2~3 步必胜”局面; |
||||
|
3. **推荐目标**:首条可行逃生路径长度在 `[4, 9]` 区间。 |
||||
|
|
||||
|
若连续重试超过阈值(例如 40 次),放宽“非过简性”下限一档,避免卡死生成。 |
||||
|
|
||||
|
## 6. 回合规则与难度 |
||||
|
|
||||
|
### 6.1 回合流程(固定顺序) |
||||
|
|
||||
|
1. 玩家点击相邻节点,小偷移动一步; |
||||
|
2. 立即判胜:若小偷到达出口 => `win`; |
||||
|
3. 若未胜,官兵移动一步; |
||||
|
4. 判负: |
||||
|
- 官兵与小偷同节点 => `lose`; |
||||
|
- 小偷下一回合无可移动邻格 => `lose`。 |
||||
|
|
||||
|
### 6.2 官兵逼近策略 |
||||
|
|
||||
|
- `easy`:60% 走最短路下一格,40% 走“次优候选”随机格; |
||||
|
- `normal`:85% 最短路,15% 次优随机; |
||||
|
- `hard`:100% 最短路。 |
||||
|
|
||||
|
“次优候选”定义:不会显著增大小偷距离,且仍保持追击方向。 |
||||
|
|
||||
|
### 6.3 非法输入处理 |
||||
|
|
||||
|
- 非邻接点击:忽略并提示“只能移动到相邻格”; |
||||
|
- 非 `playing` 状态点击地图:忽略。 |
||||
|
|
||||
|
## 7. UI 设计 |
||||
|
|
||||
|
### 7.1 顶部 HUD |
||||
|
|
||||
|
- 左上:`成功次数:X` |
||||
|
- 右上:`当前 seed:<seed>` |
||||
|
|
||||
|
### 7.2 开局面板 |
||||
|
|
||||
|
- 难度单选(简单/普通/困难) |
||||
|
- seed 输入框(可空) |
||||
|
- 空:自动随机 |
||||
|
- 非空:按输入值开局 |
||||
|
- `开始游戏` 按钮 |
||||
|
|
||||
|
### 7.3 对局中视觉 |
||||
|
|
||||
|
- 高亮小偷可移动邻格; |
||||
|
- 小偷、官兵、出口使用不同视觉标识; |
||||
|
- 状态提示文案(你的回合 / 官兵逼近中 / 已被包围)。 |
||||
|
|
||||
|
### 7.4 结算弹层 |
||||
|
|
||||
|
- 胜利:文案“成功逃脱!”,按钮 `重新开始`(新 seed 新局),并 `winCount + 1`; |
||||
|
- 失败:文案“你被抓住了”或“你已无路可走”,按钮: |
||||
|
- `重试`:按 `currentSnapshot` 完全恢复当前局; |
||||
|
- `新一局`:生成新 seed 新局。 |
||||
|
|
||||
|
按钮统一加点击防抖(短时禁用)避免重复触发。 |
||||
|
|
||||
|
## 8. 关键流程定义 |
||||
|
|
||||
|
### 8.1 新一局流程 |
||||
|
|
||||
|
1. 读取 UI 配置(难度、可选手动 seed); |
||||
|
2. 解析 seed(手动或自动随机); |
||||
|
3. 生成并验证地图; |
||||
|
4. 构造 `snapshot`,并进入 `playing`; |
||||
|
5. 刷新渲染。 |
||||
|
|
||||
|
### 8.2 重试流程(失败后) |
||||
|
|
||||
|
1. 校验 `currentSnapshot` 存在; |
||||
|
2. 从快照恢复全部状态(同图同起点同出口同难度同 seed); |
||||
|
3. 状态置为 `playing`; |
||||
|
4. 刷新渲染。 |
||||
|
|
||||
|
## 9. 测试与验收标准 |
||||
|
|
||||
|
### 9.1 单元测试(逻辑层) |
||||
|
|
||||
|
- 同 seed 生成一致性; |
||||
|
- 不同 seed 生成差异性; |
||||
|
- 连通性校验; |
||||
|
- 可逃脱性校验; |
||||
|
- 非过简性校验; |
||||
|
- 官兵三档策略概率行为(统计容差); |
||||
|
- 胜负判定(同格、到出口、无路可走)。 |
||||
|
|
||||
|
### 9.2 集成测试(场景层) |
||||
|
|
||||
|
- 点击相邻节点可移动,非相邻无效; |
||||
|
- 小偷一步后官兵一步; |
||||
|
- 胜利后“重新开始”进入新地图; |
||||
|
- 失败后“重试”恢复同局,“新一局”生成新局; |
||||
|
- 成功次数仅在胜利时增加。 |
||||
|
|
||||
|
### 9.3 验收清单 |
||||
|
|
||||
|
- 地图节点数稳定在 20~30; |
||||
|
- 初始小偷与官兵有距离,不贴脸开局; |
||||
|
- 所有局保证存在可逃脱可能; |
||||
|
- 但并非“随便走都赢”; |
||||
|
- seed 可复现; |
||||
|
- UI 操作路径与文案符合需求。 |
||||
|
|
||||
|
## 10. 实施拆分建议 |
||||
|
|
||||
|
建议按以下顺序进入实现计划: |
||||
|
|
||||
|
1. 先完成 `GameModel` 与地图生成/校验; |
||||
|
2. 接入 `page_chase` 基础渲染与点击移动; |
||||
|
3. 接入难度策略与胜负/结算流程; |
||||
|
4. 最后完善 HUD、seed 输入、按钮交互与测试。 |
||||
Loading…
Reference in new issue