102 lines
13 KiB
Markdown
102 lines
13 KiB
Markdown
# Repository Guidelines
|
||
|
||
## 项目结构与模块组织
|
||
本仓库是 `Cocos Creator 3.8.8` 小游戏项目。主入口在 `assets/main.ts`,主场景是 `assets/main.scene`。页面与弹窗组件集中在 `assets/prefabs/`,命名通常为 `PageXxx.ts`、`PassModal.ts`。公共逻辑位于 `assets/scripts/`:`core/` 放页面基类与视图管理,`utils/` 放 SDK、鉴权、存储、网络等工具,`config/` 放接口配置,`types/` 放类型定义。静态资源在 `assets/resources/`,编辑器配置在 `settings/v2/packages/`,设计说明在 `docs/` 与根目录分析文档中。
|
||
|
||
## 构建、调试与开发命令
|
||
先运行 `npm install`,同步 `minigame-api-typings` 依赖。日常开发主要通过 Cocos Creator 编辑器完成:使用 3.8.8 打开仓库,点击 `Play` 预览,使用 `Project > Build` 或 `Cmd+B` 构建小游戏包。若编辑器已生成 `temp/tsconfig.cocos.json`,可执行 `npx tsc --noEmit` 做一次 TypeScript 静态检查。
|
||
|
||
## 代码风格与命名约定
|
||
项目使用 TypeScript,当前代码统一为 4 空格缩进。组件类、页面类、管理器类使用 `PascalCase`,实例属性与私有方法使用 `camelCase` / `_camelCase`,管理器统一使用 `XxxManager` 后缀。新增页面、预制体、脚本请保持同名,例如 `PageLevel.prefab` 对应 `PageLevel.ts`。优先把复用逻辑放入 `assets/scripts/utils/` 或 `assets/scripts/core/`,不要把业务代码散落到场景脚本中。Cocos 资源的 `.meta` 文件必须一并提交。
|
||
|
||
## 测试与验证
|
||
仓库当前未配置 Jest、Vitest 一类自动化测试。提交前至少完成三项验证:1. 编辑器预览主流程可进入页面;2. 目标平台构建成功;3. 涉及微信能力时,在真机或开发者工具验证登录、分享、隐私授权等流程。若修改接口或体力/关卡逻辑,补充手动验证步骤到 PR 描述。
|
||
|
||
## 好友分享挑战链路
|
||
当前好友分享挑战是独立于普通闯关的一条链路,核心入口和数据流如下。
|
||
|
||
1. 选题入口在首页 `PageHome`,点击 `PK` 按钮后进入 `PageWriteLevels`,不是从普通 `PageLevel` 内发起。[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. 预览按钮只做本地预览:把 `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=xxx`,没有把题目内容塞进 query。[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)` 命中加入分享接口,再跳过首页直接打开 `PageLevel`,并带上 `params.shareMode = true`。[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` 在 `shareMode` 下会把 `_shareLevelIndex` 置为 `0`,进入 `_enterAndInitLevel()` 时直接从 `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. 分享模式通关后只会上报 `POST /share/progress`,参数是 `shareCode + levelId + passed + timeSpent`。当前代码只在答对时调用,超时和答错不会上报失败结果,所以服务端拿到的是“成功通关进度”,不是完整作答事件流。[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++`,直到分享题单做完后清掉 `ShareManager` 的内存态并 `replace('PageHome')` 返回首页。中途从超时弹窗回首页,也会先清理分享态。[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)
|
||
|
||
## 已知约束与缺口
|
||
1. `PageLevel` 的分享模式标题显示的是“第 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()` 构造 `RuntimeLevelConfig` 时没有填 `timeLimit`,而 `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. `PagePreviewLevels` 和 `PageWriteLevels` 的选题/预览都依赖“索引对应同一份 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)
|
||
|
||
## 提交与 Pull Request 规范
|
||
Git 历史采用 Conventional Commits,且摘要多为中文,例如 `feat: 支持分享关卡通关上报`、`fix: 修复关卡排序`、`docs: 添加设计文档`。请继续使用 `feat:`、`fix:`、`perf:`、`docs:` 前缀,首行聚焦单一变更。PR 需说明改动范围、影响页面或模块、验证方式;涉及 UI 请附截图或录屏,涉及微信环境差异请写明复现条件与平台。
|
||
|
||
|
||
<claude-mem-context>
|
||
# Memory Context
|
||
|
||
# $CMEM mp-xieyingeng 2026-05-10 10:19pm GMT+8
|
||
|
||
Legend: 🎯session 🔴bugfix 🟣feature 🔄refactor ✅change 🔵discovery ⚖️decision
|
||
Format: ID TIME TYPE TITLE
|
||
Fetch details: get_observations([IDs]) | Search: mem-search skill
|
||
|
||
Stats: 47 obs (10,663t read) | 538,681t work | 98% savings
|
||
|
||
### Apr 24, 2026
|
||
101 8:46a 🟣 Live label display format updated to X/Y format
|
||
114 6:40p 🟣 Dynamic Input Layout Initialization in PageLevel Prefab
|
||
115 6:41p 🟣 Dynamic Punch Block Layout for PageLevel.prefab
|
||
116 " 🔵 Layout Component Configuration for Input and Punch Blocks
|
||
119 6:42p 🟣 Dynamic Input Blocks and Punch Layout System Implemented
|
||
121 " 🟣 PageLevel Prefab Updated with punchLayout Property
|
||
122 " 🔄 Cleanup After Dynamic Block Refactoring
|
||
124 " ✅ TypeScript Compilation Check in Progress
|
||
126 6:43p ✅ TypeScript Compilation Check Extended
|
||
127 " 🔄 Complete Diff of PageLevel.ts Dynamic Block System
|
||
128 " 🔵 PageLevel.prefab Changes Not Persisted
|
||
129 6:44p 🟣 PageLevel Prefab Correctly Updated with punchLayout
|
||
130 " ✅ TypeScript Compilation Blocked - Permission Required
|
||
133 6:45p 🔄 Extracted getPunchBlockLabel Helper Method
|
||
134 " 🔄 Template Node Hiding Logic Improved
|
||
136 6:48p ⚖️ TypeScript diagnostics disabled, using IDE/linter instead
|
||
138 " 🔄 PageLevel 输入方式从单框改为逐字格子
|
||
139 " 🔄 谐音梗展示从 Label 改为动态 Block 节点
|
||
140 " ✅ PageLevel.prefab 布局位置微调
|
||
165 8:08p 🟣 PageLevel input layout simplified to single-character boxes with auto-distribution
|
||
167 8:09p 🔵 PageLevel.ts input block structure and callback stubs discovered
|
||
168 " 🟣 Auto-distribute characters across input boxes and auto-submit on completion implemented
|
||
169 " 🔴 PageLevel.ts node cleanup now calls removeFromParent before destroy
|
||
170 8:10p 🔄 PageLevel.ts full diff: single EditBox replaced with per-character block system
|
||
171 " 🔴 distributeInputText() wrapped in try/finally to guarantee flag reset
|
||
179 8:23p ✅ Game011_3.ttf font relocated from resources/ to dedicated fonts/ bundle directory
|
||
180 " 🟣 PageLoading.ts now loads fonts as a dynamic bundle after level data, before UI
|
||
181 " 🔄 AssetManager import switched to type-only import in PageLoading.ts
|
||
182 8:31p 🟣 PageLevel input UX improvement: full-string editing support
|
||
183 " 🟣 PageLevel input UX: full-string editing implemented
|
||
186 8:34p 🔴 PageLevel: clear input text on wrong answer
|
||
187 8:35p 🟣 PageLevel: delay pass modal to show punchline
|
||
189 8:36p 🔄 PageLevel: level completion reporting made fire-and-forget
|
||
191 8:45p 🔴 PageLevel: punchline block cleanup improved
|
||
192 8:46p 🟣 PageLevel.ts TitleLevel Label variable reserved
|
||
193 8:47p 🔵 PageLevel.ts level number tracking mechanism discovered
|
||
195 " 🟣 PageLevel.ts TitleLevel dynamic label update implemented
|
||
196 8:53p 🔵 PageLevel punchline not updated from enterLevel API
|
||
198 " 🔴 LevelDataManager updateLevelDetails now includes punchline
|
||
199 " 🔴 PageLevel punchline flow and empty state layout fixed
|
||
200 8:54p 🔴 LevelDataManager preserves existing punchline when enter returns null
|
||
203 9:06p 🟣 PageLevel.ts 新增图片描述标签绑定字段
|
||
205 9:07p 🟣 PageLevel.ts 图片描述标签字段对接完成
|
||
206 9:09p ✅ PageLevel.ts 回退图片描述标签字段命名
|
||
208 9:11p 🟣 LevelDataManager 增加图片描述字段存储
|
||
214 9:40p 🟣 拼图游戏关卡内 Punch Layout 显隐控制
|
||
216 " 🟣 PageLevel.ts punchline 显隐控制逻辑对接完成
|
||
|
||
Access 539k tokens of past work via get_observations([IDs]) or mem-search skill.
|
||
</claude-mem-context>
|