- 通关每关获 1 个城市冰箱贴,通关全城获 1 个城市邮票 - 冰箱贴收集册(按城市)+ 邮票收集册(按洲)+ 猫猫图鉴 - 城市主题礼物区入口统一展示三种收藏品 - playerState 新增 collectedMagnets/collectedStamps - 分享入口更新(冰箱贴/邮票/洲际成就) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16 KiB
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 |
| 华东 | 上海、南京、杭州、合肥、福州、南昌、济南、苏州、厦门、青岛、宁波 | 11(2 页) |
| 华中 | 郑州、武汉、长沙 | 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-6) | 6 个 | 每关奖励 1 个该城市特色冰箱贴 |
| 城市邮票贴 | 通关城市全部 6 关 | 1 个 | 集齐 6 个冰箱贴后自动获得城市邮票 |
| 城市猫猫 | 通关城市 Boss 关(关 6) | 1 只 | 同时获得邮票和猫猫 |
4.2 冰箱贴系统
获取规则:
- 每通关 1 个小关卡,奖励该城市 1 个特色冰箱贴
- 冰箱贴内容对应该关使用的城市特色元素(如北京关 1 → 糖葫芦冰箱贴)
- 通关动画结束后,冰箱贴从画面飞入收集册
冰箱贴收集册:
- 入口在"城市主题礼物区"
- 按城市分页展示,每页最多 6 个冰箱贴(对应 6 关)
- 已收集:彩色冰箱贴 + 关卡编号
- 未收集:灰色占位 + 锁图标
- 全城市集齐 6 个时,页面顶部显示"已完成 ✅"
冰箱贴数据:
// 冰箱贴和城市元素绑定,每关指定 1 个代表元素
{
id: 'magnet_beijing_1',
cityId: 'beijing',
levelId: 1,
elementId: 'beijing_03', // 天安门 — 该关的代表元素
name: '天安门冰箱贴',
image: 'images/magnets/beijing/magnet_beijing_1.png',
}
4.3 邮票贴系统
获取规则:
- 通关城市全部 6 关后自动获得该城市邮票贴
- 邮票贴和城市猫猫同时发放(Boss 关通关奖励)
- 获得邮票时播放"盖章"动画(邮戳落下 + 印章音效)
邮票贴收集册:
- 入口在"城市主题礼物区"
- 按洲分页展示
- 每个邮票:城市名 + 城市标志图案 + 获得日期
- 已收集:彩色邮票
- 未收集:灰色虚线框 + 城市名
- 集齐一个洲的全部邮票后,解锁"洲际旅行家"成就
邮票贴数据:
{
id: 'stamp_beijing',
cityId: 'beijing',
name: '北京邮票',
image: 'images/stamps/stamp_beijing.png',
acquiredDate: null, // 获得后写入日期
}
4.4 城市主题礼物区
入口位置: 主页底部 Tab 或城市页右上角礼物图标
包含 3 个子页面:
| 子页面 | 内容 | 进度展示 |
|---|---|---|
| 冰箱贴收集册 | 按城市分页的冰箱贴网格 | X/总数 |
| 邮票贴收集册 | 按洲分页的邮票网格 | X/Y 城市已集齐 |
| 猫猫图鉴 | 按洲分类的猫猫陈列 | X/Y 只已收集 |
总览信息栏(礼物区顶部):
- 冰箱贴:已收集 X / 总 Y 个
- 邮票:已收集 X / 总 Y 个
- 猫猫:已收集 X / 总 Y 只
4.5 分享触发
| 触发点 | 分享内容 |
|---|---|
| 获得冰箱贴 | "我收集了XX冰箱贴!" + 冰箱贴图片 |
| 获得城市邮票 | "XX城市邮票到手!" + 邮票图片 + 护照进度 |
| 集齐一个城市全部冰箱贴 | "XX城市冰箱贴全收集!" |
| 集齐一个洲全部邮票 | "亚洲旅行家达成!" + 全部邮票合照 |
4.6 与 playerState 的关系
// playerState 新增字段
{
// 冰箱贴收集
collectedMagnets: [
// { magnetId: 'magnet_beijing_1', cityId: 'beijing', levelId: 1, acquiredDate: '2026-03-28' }
],
// 邮票收集
collectedStamps: [
// { stampId: 'stamp_beijing', cityId: 'beijing', acquiredDate: '2026-03-28' }
],
// 猫猫收集(已有,不变)
collectedCats: ['beijing'],
}
---
## 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 |