80 lines
9.1 KiB
Markdown
80 lines
9.1 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Project Overview
|
||
|
||
这是一个 Cocos Creator 3.8.8 项目,用于开发小游戏/可玩广告。
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
assets/
|
||
├── main.ts # 主入口脚本
|
||
├── main.scene # 主场景
|
||
├── PageLoading.ts # 页面加载组件
|
||
├── PageLoading.prefab # 预制体
|
||
├── scripts/
|
||
│ └── utils/
|
||
│ └── BackgroundScaler.ts # 背景缩放工具组件
|
||
└── resources/
|
||
└── images/ # 图片资源
|
||
```
|
||
|
||
## Development Commands
|
||
|
||
此项目使用 Cocos Creator 编辑器进行开发:
|
||
|
||
- **打开项目**: 使用 Cocos Creator 3.8.8 打开此目录
|
||
- **运行预览**: 在 Cocos Creator 编辑器中点击 "Play" 按钮
|
||
- **构建**: 使用编辑器菜单 `Project > Build` 或快捷键 `Cmd+B`
|
||
|
||
## Editor Operations (强制约定)
|
||
|
||
**凡是涉及 prefab、scene、node、component 或 Cocos 编辑器内的任何操作,必须使用 `cocos-creator` MCP,不要手工编辑 `.prefab` / `.scene` 的 YAML/JSON 文件。**
|
||
|
||
适用范围(非穷举):
|
||
|
||
- 创建 / 修改 / 删除 prefab:`mcp__cocos-creator__prefab_*`
|
||
- 场景增删改、打开/保存场景:`mcp__cocos-creator__scene_*`
|
||
- 节点结构(增删、移动、改 transform、改属性):`mcp__cocos-creator__node_*`
|
||
- 组件挂载、属性赋值、引用绑定(Sprite/Label/Button/自定义脚本等):`mcp__cocos-creator__component_*`
|
||
- 资源管理(导入、查询 UUID、刷新、引用校验):`mcp__cocos-creator__project_*` / `mcp__cocos-creator__assetAdvanced_*`
|
||
- 场景脚本执行、调试日志、性能数据:`mcp__cocos-creator__debug_*` / `mcp__cocos-creator__sceneAdvanced_*`
|
||
|
||
允许直接编辑的文件仍是:`.ts` 脚本源代码(`assets/**/*.ts`)、纯文本配置(`tsconfig.json`、`package.json` 等)。`.prefab` / `.scene` / `.meta` 一律走 MCP,避免 UUID 错位、引用丢失、序列化格式被破坏。
|
||
|
||
操作前先用 `scene_get_current_scene` / `node_get_all_nodes` / `prefab_get_prefab_info` 等查询类工具确认当前编辑器状态,不要凭记忆操作。
|
||
|
||
## TypeScript Coding
|
||
|
||
遵循 Cocos Creator 3.x 组件系统架构:
|
||
|
||
- 使用 `@ccclass` 装饰器声明组件
|
||
- 继承 `cc.Component` 基类
|
||
- 生命周期方法: `onLoad` -> `start` -> `update` -> `onDestroy`
|
||
- 使用 `cc.` 命名空间访问引擎 API(如 `cc.view`, `cc.Node`, `cc.Component` 等)
|
||
|
||
## Friend Share Challenge Flow
|
||
|
||
当前项目里的好友分享挑战链路不是普通闯关的变体,而是一条单独的模式切换链路。
|
||
|
||
1. 发起入口在首页 `PageHome` 的 `PK` 按钮,点击后进入 `PageWriteLevels` 进行选题,而不是从普通关卡页直接发起。[assets/prefabs/PageHome.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageHome.ts#L153)
|
||
2. `PageWriteLevels` 只允许从当前用户“已通关关卡”中选题,数据来自 `CompletedLevelsManager.fetch()`;当前产品规则要求必须选满 `6` 关。[assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L140) [assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L507)
|
||
3. 预览只是本地页面跳转:`PageWriteLevels` 把 `selectedIndices + shareTitle` 传给 `PagePreviewLevels`,后者再从 `CompletedLevelsManager` 当前缓存里按索引读答案、提示和封面图,不会请求后端。[assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L525) [assets/prefabs/PagePreviewLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PagePreviewLevels.ts#L108)
|
||
4. 正式分享时,`PageWriteLevels` 会把选中的索引转成 `levelIds`,调用 `ShareManager.createShare(title, levelIds)`,命中 `POST /share` 创建挑战并拿到 `shareCode`。[assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L536) [assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L53)
|
||
5. 创建成功后,前端会尝试上传一次发起者头像昵称,再调用 `WxSDK.shareAppMessage` 发微信卡片;关键 query 只有 `shareCode`,好友侧是靠这个码重新拉题单。[assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L563) [assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L219)
|
||
6. 好友从微信卡片打开小游戏时,启动页 `PageLoading` 会从 `WxSDK.getShareCodeFromLaunch()` 读取启动参数;只要拿到 `shareCode` 且登录成功,就会调用 `ShareManager.joinShare(code)`,然后跳过首页,直接以 `shareMode=true` 打开 `PageLevel`。[assets/PageLoading.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/PageLoading.ts#L82) [assets/scripts/utils/WxSDK.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/WxSDK.ts#L302)
|
||
7. `ShareManager.joinShare()` 会把后端返回的分享关卡列表转成内存里的 `RuntimeLevelConfig[]`,首关图立即预加载,后续关卡按需懒加载;这条链路不会走普通模式的 `AuthManager.nextLevel`、`LevelDataManager`、`enterLevel`。[assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L73) [assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L150)
|
||
8. `PageLevel` 进入分享模式后,当前题数据直接来自 `ShareManager.ensureShareLevelReady(index)`,不会调用 `StaminaManager.enterLevel()`,因此分享挑战不消耗体力,也不依赖 enter 接口补答案和提示。[assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L258) [assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L330)
|
||
9. 作答判定仍在 `PageLevel.onSubmitAnswer()` 本地完成,本质就是把用户输入和 `config.answer` 做字符串比较;答对后显示通关链路并切到下一题,答错则弹错误弹窗。[assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L1504)
|
||
10. 分享模式下只有答对时会调用 `ShareManager.reportLevelProgress(levelId, true, timeSpent)` 上报 `POST /share/progress`。当前没有把答错或超时作为失败事件上报,所以服务端拿到的是“成功进度”,不是完整挑战行为流。[assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L1566) [assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L187)
|
||
11. 分享模式下切下一题只会 `_shareLevelIndex++`;全部做完后清空分享态并回首页。超时弹窗点回首页时也会先清理分享态,避免脏状态残留。[assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L1831) [assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L1880)
|
||
|
||
## Current Gaps
|
||
|
||
1. 分享模式标题展示的是分享内序号 `第 1 关 / 第 2 关`,不是题库真实关卡号。[assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L1004)
|
||
2. `PassModal` 和 `TimeoutModal` 内部的分享按钮发的是普通 `level=...` query,不是好友挑战 `shareCode`,所以它们目前不属于这条好友分享挑战链路。[assets/prefabs/PassModal.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PassModal.ts#L453) [assets/prefabs/TimeoutModal.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/TimeoutModal.ts#L136)
|
||
3. `ShareManager.joinShare()` 当前没有把后端题目的 `timeLimit` 写入 `RuntimeLevelConfig`,而 `PageLevel` 会用 `config.timeLimit ?? 60` 兜底,因此分享题默认统一 60 秒。[assets/scripts/utils/ShareManager.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/scripts/utils/ShareManager.ts#L91) [assets/prefabs/PageLevel.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageLevel.ts#L416)
|
||
4. 选题页和预览页通过 `selectedIndices` 对同一份 completed list 建立映射,若列表在页面间发生刷新或顺序变化,存在按索引错位的风险;更稳妥的传参应该是 `levelIds` 或完整快照。[assets/prefabs/PageWriteLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PageWriteLevels.ts#L528) [assets/prefabs/PagePreviewLevels.ts](/Users/richard/Documents/code/cocosProject/mp-xieyingeng/assets/prefabs/PagePreviewLevels.ts#L192)
|