Files
wechat-minigame/docs/02-game-design.md
manpengan 86a7b32b8f design: 五层收集体系 — 冰箱贴/邮票/猫猫/动物/洲地图
5 层收集品和导航层级一一对应:
- 关卡→冰箱贴, 城市→邮票, 地区→猫猫(不同品种),
  国家→代表动物, 大洲→洲地图
- 城市主题礼物区含 5 个收集册(Tab 切换)
- playerState 新增 collectedRegionCats/collectedAnimals/collectedMaps
- 14 国代表动物 + 8 地区猫猫品种 + 6 洲地图风格定义

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

593 lines
20 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
```
#### 洲选择页(主页面 3×3
9 格全部填满7 大洲 + 2 个特殊入口。
```
┌────────┬────────┬────────┐
│ 亚洲 │ 欧洲 │ 北美洲 │
├────────┼────────┼────────┤
│ 南美洲 │ 非洲 │ 大洋洲 │
├────────┼────────┼────────┤
│ 南极洲 │主题大混战│敬请期待│
└────────┴────────┴────────┘
```
**第 8 格 — 主题大混战:**
- 从全部已解锁城市的素材池中随机抽取元素,生成一局独立关卡
- 每次进入素材组合不同seed = 时间戳,不可复现)
- 一局内可能出现北京糖葫芦 + 东京寿司 + 曼谷冬阴功的混搭
- 不属于任何城市,不计入城市进度
- 通关奖励:随机城市冰箱贴 ×1 或道具补给
- 解锁条件:至少通关 2 个城市后开放
- 难度中等偏上8-10 种元素3-4 层,中高遮挡)
**第 9 格 — 敬请期待:**
- 固定显示"敬请期待"+ 锁定图标
- 后续可替换为新玩法入口(如:竞速模式、好友对战、赛季挑战等)
- 点击弹出提示:"新玩法即将上线,敬请期待!"
#### 亚洲国家页
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. 收集系统 — 城市主题礼物区
5 层收集体系,和导航层级一一对应,存放在"城市主题礼物区"。
### 4.1 五层收集品总览
| 层级 | 收藏品 | 获取条件 | 数量 | 收集册 |
|------|--------|---------|------|--------|
| 关卡 | 城市冰箱贴 | 通关每个小关卡 | 每城 6 个 | 冰箱贴收集册 |
| 城市 | 城市邮票贴 | 通关城市全部 6 关 | 每城 1 个 | 邮票贴收集册 |
| 地区 | 地区猫猫头像贴 | 通关地区内全部城市 | 每地区 1 个 | 猫猫收集册 |
| 国家 | 国家动物形象贴 | 通关国家内全部城市/地区 | 每国 1 个 | 动物收集册 |
| 大洲 | 洲地图 | 通关洲内全部国家 | 每洲 1 张 | 地图收集册 |
```
通关关卡 → 冰箱贴
└→ 集齐 6 关 → 城市邮票
└→ 集齐地区全城市 → 地区猫猫(不同品种)
└→ 集齐国家全地区 → 国家代表动物
└→ 集齐洲全国家 → 洲地图
```
### 4.2 冰箱贴(关卡级)
- 通关每个小关卡奖励 1 个该城市特色冰箱贴
- 冰箱贴对应该关的代表元素(如北京关 1 → 天安门冰箱贴)
- 通关动画后冰箱贴飞入收集册
```javascript
{
id: 'magnet_beijing_1',
cityId: 'beijing',
levelId: 1,
elementId: 'beijing_03',
name: '天安门冰箱贴',
image: 'images/magnets/beijing/magnet_beijing_1.png',
}
```
### 4.3 邮票贴(城市级)
- 通关城市全部 6 关后自动获得
- 获得时播放"盖章"动画(邮戳落下 + 印章音效)
- 每张邮票:城市名 + 标志图案 + 获得日期
```javascript
{
id: 'stamp_beijing',
cityId: 'beijing',
name: '北京邮票',
image: 'images/stamps/stamp_beijing.png',
}
```
### 4.4 猫猫头像贴(地区级)
- 通关地区内全部城市后获得该地区专属猫猫
- **每个地区的猫猫品种不同**,体现地域特色
| 地区 | 猫猫品种 | 设计方向 |
|------|---------|---------|
| 华北 | 中华狸花猫 | 虎斑花纹 + 红围巾 |
| 东北 | 临清狮猫 | 白色长毛 + 雪花耳饰 |
| 华东 | 三花猫 | 三色 + 丝绸蝴蝶结 |
| 华中 | 橘猫 | 胖橘 + 辣椒项链 |
| 华南 | 奶牛猫 | 黑白 + 木棉花簪 |
| 西南 | 玄猫 | 全黑 + 银饰耳坠 |
| 西北 | 黄狸猫 | 沙色 + 敦煌丝带 |
| 港澳台 | 玳瑁猫 | 棕黑花色 + 珍珠耳环 |
> 非中国国家不设地区层级,跳过此奖励,直接从城市邮票到国家动物。
```javascript
{
id: 'cat_region_north_china',
regionId: 'north_china',
breed: '中华狸花猫',
name: '小狸',
image: 'images/cats/region/cat_north_china.png',
}
```
### 4.5 国家动物形象贴(国家级)
- 通关国家内全部城市后获得该国代表动物
- 动物选最具国家辨识度的标志性物种
| 国家 | 代表动物 | 设计方向 |
|------|---------|---------|
| 中国 | 大熊猫 | 竹子 + 国旗配色 |
| 日本 | 柴犬 | 和风围巾 |
| 韩国 | 珍岛犬 | 韩服小帽 |
| 泰国 | 大象 | 泰式花环 |
| 新加坡 | 鱼尾狮 | 金沙造型 |
| 土耳其 | 安哥拉猫 | 蓝眼异瞳 |
| 法国 | 高卢鸡 | 贝雷帽 |
| 英国 | 柯基犬 | 皇冠 |
| 意大利 | 意大利狼 | 罗马斗篷 |
| 美国 | 白头鹰 | 星条旗翅膀 |
| 澳大利亚 | 袋鼠 | 拳击手套 |
| 巴西 | 金刚鹦鹉 | 桑巴羽冠 |
| 埃及 | 法老猎犬 | 法老头饰 |
| 印度 | 孟加拉虎 | 莲花 |
> 更多国家动物随城市扩展逐步添加。扁平冰箱贴风格,和城市元素视觉统一。
```javascript
{
id: 'animal_china',
countryId: 'china',
animal: '大熊猫',
name: '团团',
image: 'images/animals/animal_china.png',
}
```
### 4.6 洲地图(大洲级)
- 通关洲内全部国家后获得该洲完整地图
- 地图上标注所有已通关城市的位置
- 获得时播放地图展开动画(卷轴铺开 + 城市点亮)
| 洲 | 地图风格 | 设计方向 |
|----|---------|---------|
| 亚洲 | 丝绸之路风 | 暖色调 + 古地图纹理 |
| 欧洲 | 航海图风 | 羊皮纸 + 罗盘 |
| 北美洲 | 公路旅行风 | 66 号公路 + 路标 |
| 南美洲 | 探险地图风 | 丛林 + 河流 |
| 非洲 | 大草原风 | 日落 + 金合欢树 |
| 大洋洲 | 珊瑚礁风 | 海洋蓝 + 珊瑚 |
```javascript
{
id: 'map_asia',
continentId: 'asia',
name: '亚洲地图',
image: 'images/maps/map_asia.png',
}
```
### 4.7 城市主题礼物区
**入口位置:** 主页底部 Tab 或城市页右上角礼物图标
**包含 5 个收集册Tab 切换):**
| 收集册 | 内容 | 分页方式 | 进度 |
|--------|------|---------|------|
| 🧲 冰箱贴册 | 每关获得的城市冰箱贴 | 按城市分页,每页 6 格 | X/总数 |
| 📮 邮票册 | 每城获得的城市邮票 | 按洲分页 | X/Y 城市 |
| 🐱 猫猫册 | 每地区获得的猫猫头像 | 按国家分页 | X/Y 地区 |
| 🐾 动物册 | 每国获得的代表动物 | 按洲分页 | X/Y 国家 |
| 🗺️ 地图册 | 每洲获得的洲地图 | 一页展示全部 | X/6 洲 |
**总览信息栏(礼物区顶部):**
- 🧲 冰箱贴 X/Y · 📮 邮票 X/Y · 🐱 猫猫 X/Y · 🐾 动物 X/Y · 🗺️ 地图 X/6
### 4.8 分享触发
| 触发点 | 分享内容 |
|--------|---------|
| 获得冰箱贴 | "我收集了XX冰箱贴" + 冰箱贴图片 |
| 获得城市邮票 | "XX城市邮票到手" + 邮票图片 |
| 获得地区猫猫 | "华北狸花猫收入囊中!" + 猫猫图片 |
| 获得国家动物 | "中国大熊猫 GET" + 动物图片 |
| 获得洲地图 | "亚洲地图集齐!" + 地图全景 |
| 五册全满里程碑 | "世界旅行家达成!" + 五册合照 |
### 4.9 与 playerState 的关系
```javascript
// playerState 收集字段
{
collectedMagnets: [
// { magnetId, cityId, levelId, acquiredDate }
],
collectedStamps: [
// { stampId, cityId, acquiredDate }
],
collectedRegionCats: [
// { catId, regionId, acquiredDate }
],
collectedAnimals: [
// { animalId, countryId, acquiredDate }
],
collectedMaps: [
// { mapId, continentId, acquiredDate }
],
}
---
## 5. 每日挑战
| 项目 | 规格 |
|------|------|
| 内容 | 每天 1 个随机城市的特殊关卡 |
| 难度 | 比普通关卡略高更多物件种类更深堆叠 |
| 奖励 | 道具补给Undo ×2+ 特殊明信片 |
| 生成方式 | 程序化生成基于难度参数随机组合 |
---
## 6. 广告入口设计
| 广告类型 | 触发点 | 频次控制 |
|---------|--------|---------|
| 激励视频 | 失败后"复活"清空暂存槽继续 | 每局最多 1 |
| 激励视频 | 使用额外道具重排/撤回/移出 | 每种每局 1 |
| 激励视频 | 通关后"双倍奖励" | 每局可选 |
| 激励视频 | 每日签到奖励翻倍 | 每日 1 |
| 插屏广告 | 通关结算后非失败后 | 3 1 |
原则**失败后不弹插屏**避免负面情绪叠加激励视频全部可选不强制
---
## 7. 分享入口设计
| 触发点 | 分享内容 | 奖励 |
|--------|---------|------|
| 通关小关卡 | "我收集了XX冰箱贴" + 冰箱贴图片 | 道具补给Undo ×1 |
| 通关城市 | "XX城市邮票到手" + 邮票 + 猫猫 | 道具补给Shuffle ×1 |
| 集齐城市冰箱贴 | "XX城市冰箱贴全收集" | 特殊明信片 |
| 集齐洲邮票 | "亚洲旅行家达成!" + 全部邮票合照 | 特殊明信片 |
| 每日挑战通关 | 挑战结果卡片 | 道具补给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 |