Files
wechat-minigame/docs/02-game-design.md
manpengan d7bea9aed5 nav: 全量 world-catalog + status active/planned 分层
- world-catalog.js: 6洲48国127城市全量 NavNode catalog
  - 统一 schema(isEnabled → status: active|planned)
  - 64 个 NavNode 覆盖所有洲/国家/地区
- runtime-nav.js: 从 catalog 自动过滤 active 节点
  - MVP_OVERRIDES 机制跳过国家层直连城市
  - V1.1+ 删除覆写即恢复完整层级
- 删除 future-catalog.js,旧 shim 指向 world-catalog
- game-design 2.3 更新 schema + Framework Ready 说明

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:37:17 +08:00

396 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 02 Game Design — 城市抓猫猫
## 1. 核心玩法规则
### 1.1 基础机制
抓大鹅式堆叠三消:
- 场景中多层堆叠物件(城市特色元素:冰箱贴、美食、建筑、动物等)
- 上层物件遮挡下层,只有**未被完全遮挡**的物件可点击拾取
- 底部 **7 格暂存槽**
- 点击物件 → 飞入暂存槽 → 3 个同类物件自动消除
- 暂存槽满 7 格且无法消除 → 游戏失败
### 1.2 胜利/失败条件
| 条件 | 规则 |
|------|------|
| 胜利 | 清除场景中所有物件 |
| 失败 | 暂存槽满 7 格无法消除 |
| 时间 | 无时间限制MVP 阶段),靠物件数量控制局时 2-4 分钟 |
### 1.3 道具系统MVP
道具只操作暂存槽,不操作场景物件,避免恢复堆叠遮挡的复杂度。
| 道具 | 效果 | 免费额度 | 额外使用 |
|------|------|---------|---------|
| 撤回 Undo | 将暂存槽最后放入的 1 个物件移回场景顶层(不恢复原位,放到顶层空闲位置) | 每局 3 次 | 激励视频 |
| 移出 Remove | 将暂存槽中 3 个物件移到旁路寄存区1 格),下次有任意消除发生时自动回归暂存槽 | 每局 1 次 | 激励视频 |
| 洗牌 Shuffle | 重新随机排列场景中所有剩余物件的位置和层级 | 每局 1 次 | 激励视频 |
**道具状态转移表:**
```
暂存槽状态:[A][B][C][D][E][F][G] 7 格)
旁路寄存区:[X][Y][Z] 3 格,仅 Remove 道具使用)
── Undo ──
前置:暂存槽非空
操作:取暂存槽末位 1 个物件 → 放回场景顶层可见位置
后置:暂存槽空出 1 格
特殊:如果暂存槽为空则道具不可用(置灰)
── Remove ──
前置:暂存槽已用 ≥ 3 格 且 旁路寄存区为空
操作:取暂存槽中 3 个不同类型的物件 → 移入旁路寄存区
后置:暂存槽空出 3 格
回归条件:场景中发生任意一次三消 → 旁路寄存区物件自动回归暂存槽
回归溢出:如果回归时暂存槽已满 7 格 → 先回归再判定失败(即回归物件 + 当前槽位 > 7 则游戏失败)
限制:旁路寄存区非空时不可再次使用 Remove
── Shuffle ──
前置:场景中剩余物件 > 0
操作:所有场景物件重新随机分配位置和层级
后置:物件总数和种类不变,堆叠关系重新生成
特殊Shuffle 后需保证至少 30% 物件可点击(同关卡生成约束)
```
**道具交互约束:**
- Undo 和 Remove 互斥使用:旁路寄存区非空时 Undo 不可用(避免回归顺序混乱)
- Shuffle 与其他道具无冲突
- 复活(激励视频):清空暂存槽 + 清空旁路寄存区,场景状态不变,继续游戏
### 1.4 操作交互
| 交互 | 规格 |
|------|------|
| 拾取方式 | 单点点击(不用拖拽) |
| 飞入动画 | 贝塞尔曲线路径0.2s |
| 消除动画 | 闪光 + 缩放消失0.3s |
| 通关动画 | 撒花 + 城市特色猫猫出现1s |
---
## 2. 地图结构
### 2.1 MVP 导航(当前实现)
MVP 只开放亚洲 6 城市,直入城市选择页,不启用完整多级导航。
```
启动 → 亚洲城市页3x3 棋盘6 城市)→ 关卡
```
- 跳过洲选择页(只有 1 个洲,多余点击)
- 跳过国家/地区层级
- 6 城市平铺在一页 3x3 棋盘中
- 其他洲的入口不显示
**MVP 城市列表(固定 6 城):**
| 序号 | 城市 | 国家 | 解锁条件 |
|------|------|------|---------|
| 1 | 北京 | 中国 | 默认解锁 |
| 2 | 东京 | 日本 | 通关北京 |
| 3 | 曼谷 | 泰国 | 通关东京 |
| 4 | 首尔 | 韩国 | 通关曼谷 |
| 5 | 新加坡 | 新加坡 | 通关首尔 |
| 6 | 伊斯坦布尔 | 土耳其 | 通关新加坡 |
### 2.2 V1.1+ 完整导航(后续启用)
城市数量超过 9 时启用完整多级导航,每页 3×3 棋盘,超过 9 项翻页。
```
洲选择3x3
└── 国家选择3x3分页
└── 城市选择3x3分页
└── 关卡
```
中国因城市多41 城),额外增加地区层级:
```
亚洲 → 中国 → 地区3x3→ 城市3x3
亚洲 → 日本 → 城市3x3
```
#### 洲选择页
6 个洲1 页:亚洲、欧洲、北美洲、南美洲、非洲、大洋洲。
#### 亚洲国家页
18 国,分 2 页:
- Page 1: 中国、日本、韩国、泰国、新加坡、越南、马来西亚、印度尼西亚、菲律宾
- Page 2: 印度、阿联酋、土耳其、以色列、尼泊尔、柬埔寨、斯里兰卡、缅甸、蒙古
#### 中国地区页
8 个地区1 页:
| 地区 | 城市 | 数量 |
|------|------|------|
| 华北 | 北京、天津、石家庄、太原、呼和浩特 | 5 |
| 东北 | 沈阳、长春、哈尔滨、大连 | 4 |
| 华东 | 上海、南京、杭州、合肥、福州、南昌、济南、苏州、厦门、青岛、宁波 | 112 页) |
| 华中 | 郑州、武汉、长沙 | 3 |
| 华南 | 广州、深圳、南宁、海口、三亚 | 5 |
| 西南 | 成都、重庆、贵阳、昆明、拉萨 | 5 |
| 西北 | 西安、兰州、西宁、银川、乌鲁木齐 | 5 |
| 港澳台 | 香港、澳门、台北 | 3 |
> 港澳台统一为 3 城(香港、澳门、台北),文档和索引一致。
### 2.3 导航数据合同
所有导航层级使用统一的 NavNode schema定义在 `js/content/navigation/nav-schema.js`
| 字段 | 类型 | 说明 |
|------|------|------|
| `type` | string | `continent` / `country` / `region` / `city-group` |
| `id` | string | 全局唯一标识 |
| `parentId` | string\|null | 父节点 id洲级为 null |
| `name` | string | 中文名 |
| `nameEn` | string | 英文名 |
| `sortOrder` | number | 同级排序 |
| `themeColor` | string | 主题色 HEX |
| `childType` | string\|null | 子节点类型:`country` / `region` / `city` / null |
| `childIds` | string[] | 当前可消费的子节点 id仅已启用的 |
| `pageSize` | number | 每页格子数,默认 9 |
| `status` | string | `'active'`(当前可运行)/ `'planned'`(未来规划) |
| `isUnlockedByDefault` | boolean | 是否默认解锁 |
分页通过 `shared/pagination.js``paginate(childIds, pageSize)` 动态计算,不手写 page 常量。
Framework Ready: 全量 6 洲 48 国 127 城市的 catalog 已搭好,扩城市只需加 CityManifest + 改 status 为 active。
**数据文件分层:**
| 文件 | 用途 | 是否进入 runtime |
|------|------|-----------------|
| `navigation/runtime-nav.js` | 当前版本可消费的导航节点(从 world-catalog 自动过滤) | ✅ 是 |
| `navigation/world-catalog.js` | 全量世界导航规划(含 active + planned | ✅ 是runtime-nav 从中过滤 active 节点) |
| `navigation/nav-schema.js` | NavNode schema 定义 + 验证 | ✅ 是(类型定义) |
| `docs/city-roadmap.md` | 全量 127 城市路线图 | ❌ 否 |
### 2.4 城市封面设计
每个格子显示:
- 猫猫头像(已解锁:彩色,未解锁:灰色剪影)
- 名称(中文)
- 进度(已解锁:"X/6 关",未解锁:"🔒"
### 2.5 分页交互
- 左右滑动翻页,底部圆点指示器
- 翻页动画 0.3s 弹性过渡
- MVP 只有 1 页 6 城市,无需翻页
### 2.6 解锁规则
- 同级顺序解锁(通关前一个解锁下一个)
- 第一个项目默认解锁
- MVP北京默认解锁顺序通关解锁后续城市
- V1.1+:跨层级解锁(通关一个国家所有城市后解锁下一个国家)
---
## 3. 城市猫猫系统
### 3.1 猫猫收集
- 每个城市对应 1 只特色猫猫
- 通关该城市所有 6 关 → 获得猫猫收集卡
- 猫猫头像作为城市封面显示在地图上
### 3.2 猫猫设计规则
每只猫猫的差异化维度:
| 维度 | 说明 |
|------|------|
| 品种暗示 | 不写实,用颜色和花纹暗示 |
| 城市穿戴 | 城市特色装饰(东京猫戴招财猫面具、北京猫戴虎头帽) |
| 视觉风格 | 统一扁平冰箱贴风格,确保一致性 |
### 3.3 猫猫展示
| 场景 | 表现 |
|------|------|
| 通关城市 | 猫猫出场动画(从屏幕外跳入 + 特效) |
| 图鉴页面 | 已收集猫猫陈列展示 |
| 未收集 | 灰色剪影 + "???" |
---
## 4. 图鉴系统
### 4.1 城市图鉴
- 记录每个城市的通关状态、星级、特色元素收集进度
- 展示该城市文化小知识1-2 句话)
### 4.2 猫猫图鉴
- 已收集猫猫陈列(按洲分类)
- 每只猫猫有名字 + 1 句话介绍
- 收集进度X/Y 只
### 4.3 护照系统
- 每通关一个城市,护照盖一个章
- 护照页面可分享为"明信片"
- 护照进度是核心成就展示
---
## 5. 每日挑战
| 项目 | 规格 |
|------|------|
| 内容 | 每天 1 个随机城市的特殊关卡 |
| 难度 | 比普通关卡略高(更多物件种类、更深堆叠) |
| 奖励 | 道具补给Undo ×2+ 特殊明信片 |
| 生成方式 | 程序化生成(基于难度参数随机组合) |
---
## 6. 广告入口设计
| 广告类型 | 触发点 | 频次控制 |
|---------|--------|---------|
| 激励视频 | 失败后"复活"(清空暂存槽继续) | 每局最多 1 次 |
| 激励视频 | 使用额外道具(重排/撤回/移出) | 每种每局 1 次 |
| 激励视频 | 通关后"双倍奖励" | 每局可选 |
| 激励视频 | 每日签到奖励翻倍 | 每日 1 次 |
| 插屏广告 | 通关结算后(非失败后) | 每 3 局 1 次 |
原则:**失败后不弹插屏**(避免负面情绪叠加),激励视频全部可选不强制。
---
## 7. 分享入口设计
| 触发点 | 分享内容 | 奖励 |
|--------|---------|------|
| 通关城市 | 城市猫猫卡片 + "我解锁了XX猫" | 道具补给Undo ×1 |
| 护照盖章 | 护照截图 + 收集进度 | 道具补给Shuffle ×1 |
| 每日挑战通关 | 挑战结果卡片 | 道具补给Undo ×2 |
| 图鉴里程碑 | "已收集X只猫猫" | 特殊明信片 |
分享卡片设计:猫猫形象 + 城市背景色 + 进度信息 + 小程序入口按钮。
---
## 8. 难度设计思路
### 8.1 难度参数
| 参数 | 范围 | 说明 |
|------|------|------|
| 物件种类数 | 6-12 | 种类越多,匹配越难 |
| 每种物件数量 | 3 的倍数(通常 3 或 6 | 必须是 3 的倍数保证可消除 |
| 堆叠层数 | 2-5 层 | 层数越多,可见物件越少 |
| 遮挡密度 | 低/中/高 | 物件重叠面积占比 |
| 总物件数 | 18-60 | 局时控制核心参数 |
### 8.2 城市内难度曲线
```
关1: 6种 × 3个 = 18件, 2层, 低遮挡 → 新手教学
关2: 7种 × 3个 = 21件, 2层, 低遮挡 → 轻松熟悉
关3: 8种 × 3个 = 24件, 3层, 中遮挡 → 开始有策略
关4: 9种 × 3个 = 27件, 3层, 中遮挡 → 需要思考
关5: 10种 × 3个 = 30件, 4层, 中高遮挡 → 考验规划
关6: 10种 × 3-6个 = 36件, 4层, 高遮挡 → Boss关
```
### 8.3 跨城市难度递进
| 城市序号 | 定位 | 特点 |
|---------|------|------|
| 城市 1北京 | 教学城市 | 最简单,引导玩家熟悉机制 |
| 城市 2-3 | 平滑上升 | 物件种类增加,层级不变 |
| 城市 4-5 | 进阶挑战 | 引入更高层级 + 更多种类 |
| 城市 6 | 挑战级 | 最大物件数 + 最深堆叠 |
---
## 9. 玩家存档模型
所有玩家数据持久化到 `wx.Storage`key 为 `player_state`
### 9.1 存档 Schema
```javascript
const playerState = {
// 版本控制(存档迁移用)
saveVersion: 1,
// 城市进度
unlockedCities: ['beijing'], // 已解锁城市 id 列表
levelProgress: {
// city_id: { levelId: { stars: 0-3, completed: bool, bestMoves: number } }
beijing: {
1: { stars: 3, completed: true },
2: { stars: 2, completed: true },
// ...
},
},
// 收集
collectedCats: ['beijing'], // 已收集猫猫的城市 id
passportStamps: ['beijing'], // 已盖章城市 id
// 道具库存
inventory: {
undo: 3, // 撤回次数
remove: 1, // 移出次数
shuffle: 1, // 洗牌次数
},
// 每日挑战
dailyChallenge: {
date: '2026-03-28', // 上次挑战日期YYYY-MM-DD
completed: false,
cityId: 'tokyo', // 今日挑战城市
seed: 12345, // 关卡生成种子
},
// 广告冷却
adCooldowns: {
interstitialCount: 0, // 今日插屏已展示次数
lastInterstitialTime: 0, // 上次插屏时间戳
lastRewardDate: '2026-03-28', // 上次激励视频日期
},
// 设置
settings: {
soundEnabled: true,
musicEnabled: true,
vibrationEnabled: true,
},
// 统计
stats: {
totalGamesPlayed: 0,
totalGamesWon: 0,
totalShareCount: 0,
firstPlayDate: '2026-03-28',
},
}
```
### 9.2 存档读写规则
| 规则 | 说明 |
|------|------|
| 读取时机 | 游戏启动时读取一次,缓存在内存 |
| 写入时机 | 关卡通关/失败、道具使用、城市解锁、设置变更时写入 |
| 写入方式 | `wx.setStorageSync('player_state', state)` 同步写入 |
| 版本迁移 | 读取时检查 `saveVersion`,低于当前版本则执行迁移函数 |
| 数据上限 | wx.Storage 上限 10MB预估存档 < 50KB |