@kkarum/framework 2.3.18 → 2.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -93
- package/docs/CODEX_GUIDE.md +219 -0
- package/docs/CODEX_GUIDE.md.meta +6 -0
- package/docs/ERROR_HANDLING.md +233 -0
- package/docs/ERROR_HANDLING.md.meta +6 -0
- package/docs/FRAMEWORK_API.md +414 -0
- package/docs/FRAMEWORK_API.md.meta +6 -0
- package/docs/FRAMEWORK_EXAMPLES.md +309 -0
- package/docs/FRAMEWORK_EXAMPLES.md.meta +6 -0
- package/docs/FRAMEWORK_OVERVIEW.md +127 -0
- package/docs/FRAMEWORK_OVERVIEW.md.meta +6 -0
- package/docs/FRAMEWORK_PATTERNS.md +261 -0
- package/docs/FRAMEWORK_PATTERNS.md.meta +6 -0
- package/docs/FRAMEWORK_USAGE.md +344 -0
- package/docs/FRAMEWORK_USAGE.md.meta +6 -0
- package/docs/MCP_INTEGRATION.md +241 -0
- package/docs/MCP_INTEGRATION.md.meta +6 -0
- package/docs/UI_DEVELOPMENT_GUIDE.md +295 -0
- package/docs/UI_DEVELOPMENT_GUIDE.md.meta +6 -0
- package/docs.meta +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,93 +1,191 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
# Framework
|
|
2
|
+
|
|
3
|
+
## AI 工具使用约定
|
|
4
|
+
|
|
5
|
+
Codex / AI 工具生成本项目业务代码时必须遵守:
|
|
6
|
+
|
|
7
|
+
- 获取 `AssetProperty` 使用点访问:`FW.Entry.getComponent(ShopAssetConfig).preLoad.prefab.ShopLayer`,不要使用 `["ShopLayer"]`。
|
|
8
|
+
- `LayerController` 不查找节点或组件;节点/组件引用定义在对应 `FW.Layer` 中,节点用 `FWPropertyNode`,组件用 `FWPropertyComponent`,变量名与节点名一致。
|
|
9
|
+
- 默认不要在业务层调用 `invoke()`,除非用户明确要求。
|
|
10
|
+
- 新增业务 bundle 必须提供 `FW.Registry` 注册表,并在文件末尾调用 `FW.Framework.addRegistry()`;`bundleName` 和 `addRegistry()` 的 key 必须一致,统一使用小写 bundle 名。
|
|
11
|
+
|
|
12
|
+
Registry 示例:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { RegisterAssetConfig } from "../config/RegisterAssetConfig";
|
|
16
|
+
import { RegisterLogic } from "../logic/RegisterLogic";
|
|
17
|
+
|
|
18
|
+
export class RegisterRegistry extends FW.Registry {
|
|
19
|
+
bundleName = "register";
|
|
20
|
+
logic: FW.Newable<FW.Logic> = RegisterLogic;
|
|
21
|
+
config: FW.Newable<FW.AssetConfig> = RegisterAssetConfig;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
FW.Framework.addRegistry("register", RegisterRegistry);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`assets/framework` 是面向 Cocos Creator 2.x 的自写业务框架,核心目标是把业务模块、UI Layer、资源、事件、网络、定时器、对象池和异步流程统一到 `FW` 全局命名空间下管理。
|
|
28
|
+
|
|
29
|
+
本 README 只做快速总览。详细开发规范请阅读 `assets/framework/docs/` 下的文档。
|
|
30
|
+
|
|
31
|
+
## 核心入口
|
|
32
|
+
|
|
33
|
+
框架初始化后会创建全局 `FW`:
|
|
34
|
+
|
|
35
|
+
- `FW.Framework`:依赖注入容器,负责注册和获取业务组件。
|
|
36
|
+
- `FW.Entry`:业务统一入口,聚合所有管理器。
|
|
37
|
+
- `FW.Log`:统一日志输出。
|
|
38
|
+
- `FW.SystemDefine`:框架枚举。
|
|
39
|
+
- `FW.EventDefine`:系统事件枚举。
|
|
40
|
+
|
|
41
|
+
业务代码应优先通过 `FW.Entry` 使用框架能力,不要直接 new 框架管理器。
|
|
42
|
+
|
|
43
|
+
## 主要模块
|
|
44
|
+
|
|
45
|
+
| 模块 | 说明 |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `FW.Registry` | bundle 注册表,声明 Logic/Data/Config/Sender/Handle |
|
|
48
|
+
| `FW.FrameworkBase` | 业务基类,提供依赖获取、性能记录和错误包装 |
|
|
49
|
+
| `FW.Logic` | 业务流程 |
|
|
50
|
+
| `FW.Data` | 业务数据 |
|
|
51
|
+
| `FW.AssetConfig` | 资源配置 |
|
|
52
|
+
| `FW.LayerController` | UI Layer 控制器 |
|
|
53
|
+
| `FW.Entry.resMgr` | bundle 和资源加载/释放 |
|
|
54
|
+
| `FW.Entry.layerMgr` | UI Layer 打开、关闭、队列和栈 |
|
|
55
|
+
| `FW.Entry.uiMgr` | UI 事件注册、节点查找、按钮状态 |
|
|
56
|
+
| `FW.Entry.evtMgr` | 框架事件总线 |
|
|
57
|
+
| `FW.Entry.timeMgr` | 游戏生命周期定时器 |
|
|
58
|
+
| `FW.Entry.promiseMgr` | 可取消、超时、重试的 Promise |
|
|
59
|
+
| `FW.Entry.socketMgr` | Socket 连接管理 |
|
|
60
|
+
| `FW.Entry.objectMgr` | 对象池 |
|
|
61
|
+
| `FW.Entry.taskMgr` | 分帧任务 |
|
|
62
|
+
|
|
63
|
+
## 推荐业务结构
|
|
64
|
+
|
|
65
|
+
新增业务功能时,推荐按 bundle 拆分:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
assets/<bundle>/
|
|
69
|
+
registry/<Bundle>Registry.ts
|
|
70
|
+
logic/<Bundle>Logic.ts
|
|
71
|
+
data/<Bundle>Data.ts
|
|
72
|
+
config/<Bundle>AssetConfig.ts
|
|
73
|
+
socket/<Bundle>Sender.ts
|
|
74
|
+
socket/<Bundle>Handle.ts
|
|
75
|
+
ui/<Feature>/<Feature>LayerController.ts
|
|
76
|
+
prefab/<Feature>Layer.prefab
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
命名必须保留框架后缀,例如 `ShopLogic`、`ShopData`、`ShopAssetConfig`、`ShopSender`、`ShopHandle`。框架会根据类名和 bundle 名自动推断依赖。
|
|
80
|
+
|
|
81
|
+
## UI 开发约定
|
|
82
|
+
|
|
83
|
+
UI 页面、弹窗、常驻面板应使用 `FW.LayerController`:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
await FW.Entry.layerMgr.openAsync({
|
|
87
|
+
type: ShopLayerController,
|
|
88
|
+
args: { tab: "hot" },
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
LayerController 中:
|
|
93
|
+
|
|
94
|
+
- 使用 `this.find()` 查找节点。
|
|
95
|
+
- 使用 `this.cc()` 绑定按钮事件。
|
|
96
|
+
- 使用 `this.fw()` 监听框架事件。
|
|
97
|
+
- 使用 `this.close()` 关闭 Layer。
|
|
98
|
+
- 通过 `layerAssetProperty` 指向 `AssetConfig` 中的 prefab。
|
|
99
|
+
|
|
100
|
+
不要在业务代码中绕过 `layerMgr` 直接 `cc.instantiate` 业务弹窗。
|
|
101
|
+
|
|
102
|
+
## 资源开发约定
|
|
103
|
+
|
|
104
|
+
资源统一写入 `FW.AssetConfig`:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
preLoad = {
|
|
108
|
+
prefab: {
|
|
109
|
+
ShopLayer: {
|
|
110
|
+
bundle: "shop",
|
|
111
|
+
path: "prefab/ShopLayer",
|
|
112
|
+
type: cc.Prefab,
|
|
113
|
+
priorityLoaded: true,
|
|
114
|
+
autoRelease: true,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
加载资源时使用:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const prefab = await FW.Entry.resMgr.loadAsset<cc.Prefab>(assetProperty);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
不要在业务代码中散落硬编码资源路径,也不要在资源未加载时调用 `getAsset()`。
|
|
127
|
+
|
|
128
|
+
## 事件和异步
|
|
129
|
+
|
|
130
|
+
框架事件:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
FW.Entry.evtMgr.dispatch("SHOP_GOODS_CHANGED", goods);
|
|
134
|
+
FW.Entry.evtMgr.register("SHOP_GOODS_CHANGED", this.renderGoods, this);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
定时器:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
FW.Entry.timeMgr.schedule(this.tick, 1, cc.macro.REPEAT_FOREVER, this);
|
|
141
|
+
FW.Entry.timeMgr.unSchedule(this);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
异步流程:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const result = await this.invoke(
|
|
148
|
+
FW.Entry.resMgr.loadAssetData(assetProperty),
|
|
149
|
+
"loadAsset",
|
|
150
|
+
);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`invoke()` 会记录性能并统一输出错误。调用方必须处理返回 `undefined` 的情况。
|
|
154
|
+
|
|
155
|
+
## cocos-mcp 协作
|
|
156
|
+
|
|
157
|
+
使用 cocos-mcp 做 UI 自动化时:
|
|
158
|
+
|
|
159
|
+
1. 先用 `cocos_mcp_diagnose` 检查连接。
|
|
160
|
+
2. 用 `scene_get_tree` 获取真实节点路径。
|
|
161
|
+
3. 用 `asset_query` 或 `asset_resolve` 确认资源。
|
|
162
|
+
4. 用 `ui_create_tree` 或 `ui_create_node` 创建 UI。
|
|
163
|
+
5. 用 `ui_set_sprite_frame` 绑定图片。
|
|
164
|
+
6. 需要复用时用 `prefab_create_from_node` 生成 prefab。
|
|
165
|
+
7. 运行时事件优先写在 `LayerController` 中,不强行用编辑器 clickEvents。
|
|
166
|
+
|
|
167
|
+
MCP 节点路径必须使用绝对路径,例如 `/Canvas/ShopLayer/CloseButton`。
|
|
168
|
+
|
|
169
|
+
## Codex 使用原则
|
|
170
|
+
|
|
171
|
+
Codex 在本项目中新增功能时必须遵守:
|
|
172
|
+
|
|
173
|
+
- 不修改框架内部源码,除非用户明确要求维护框架。
|
|
174
|
+
- 优先复用 `FW.Entry`、`FW.FrameworkBase`、`FW.LayerController`。
|
|
175
|
+
- UI 功能走 LayerController + prefab + AssetConfig。
|
|
176
|
+
- 业务流程放 Logic,业务状态放 Data。
|
|
177
|
+
- 网络协议放 Sender/Handle。
|
|
178
|
+
- 资源路径集中在 AssetConfig。
|
|
179
|
+
- 事件、定时器、Promise、对象池全部使用框架 API。
|
|
180
|
+
|
|
181
|
+
## 详细文档
|
|
182
|
+
|
|
183
|
+
- [FRAMEWORK_OVERVIEW.md](docs/FRAMEWORK_OVERVIEW.md):框架整体架构。
|
|
184
|
+
- [FRAMEWORK_USAGE.md](docs/FRAMEWORK_USAGE.md):业务使用方式。
|
|
185
|
+
- [FRAMEWORK_API.md](docs/FRAMEWORK_API.md):常用 API 速查。
|
|
186
|
+
- [FRAMEWORK_PATTERNS.md](docs/FRAMEWORK_PATTERNS.md):新增功能模式和禁止事项。
|
|
187
|
+
- [FRAMEWORK_EXAMPLES.md](docs/FRAMEWORK_EXAMPLES.md):可复制代码示例。
|
|
188
|
+
- [CODEX_GUIDE.md](docs/CODEX_GUIDE.md):Codex 长期开发规范。
|
|
189
|
+
- [MCP_INTEGRATION.md](docs/MCP_INTEGRATION.md):cocos-mcp 自动化流程。
|
|
190
|
+
- [UI_DEVELOPMENT_GUIDE.md](docs/UI_DEVELOPMENT_GUIDE.md):UI 开发规范。
|
|
191
|
+
- [ERROR_HANDLING.md](docs/ERROR_HANDLING.md):错误处理和生命周期清理。
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Codex Guide
|
|
2
|
+
|
|
3
|
+
## AI 生成代码强制规则
|
|
4
|
+
|
|
5
|
+
以下规则优先级高于本文档中的旧示例。Codex 或其他 AI 工具为本项目生成业务代码时必须遵守:
|
|
6
|
+
|
|
7
|
+
1. 获取 `AssetProperty` 必须使用点访问,不要使用字符串下标访问。
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
// 推荐
|
|
11
|
+
return FW.Entry.getComponent(ShopAssetConfig).preLoad.prefab.ShopLayer;
|
|
12
|
+
|
|
13
|
+
// 禁止
|
|
14
|
+
return FW.Entry.getComponent(ShopAssetConfig).preLoad.prefab["ShopLayer"];
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. `LayerController` 不要查找节点或组件,不要调用 `find()` / `findComponent()` 做 UI 引用缓存。
|
|
18
|
+
UI 节点和组件引用必须定义在对应 `FW.Layer` 组件中,并使用 `FWPropertyNode` / `FWPropertyComponent` 装饰器。变量名默认必须与节点名一致。
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
@ccclass
|
|
22
|
+
export class ShopLayer extends FW.Layer {
|
|
23
|
+
@FWPropertyNode()
|
|
24
|
+
BtnClose: cc.Node = null;
|
|
25
|
+
|
|
26
|
+
@FWPropertyComponent(cc.Label)
|
|
27
|
+
TitleLabel: cc.Label = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ShopLayerController extends FW.LayerController {
|
|
31
|
+
private bindEvents() {
|
|
32
|
+
const layer = this.layer as ShopLayer;
|
|
33
|
+
this.cc(layer.BtnClose, this.onCloseClick);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. 业务层默认不要调用 `invoke()`。除非用户明确要求统一性能记录、错误包装或可恢复异步流程,否则直接 `await` 业务方法、网络方法或资源方法。
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// 推荐
|
|
42
|
+
await FW.Entry.getComponent(ShopLogic).buyGoods(goodsId);
|
|
43
|
+
|
|
44
|
+
// 仅在用户明确要求时使用
|
|
45
|
+
await this.invoke(FW.Entry.getComponent(ShopLogic).buyGoods(goodsId), "buyGoods");
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
4. 新增业务 bundle 必须提供 `FW.Registry` 注册表,并在文件末尾调用 `FW.Framework.addRegistry()`。`bundleName` 与 `addRegistry()` 的 bundle key 必须完全一致,统一使用小写 bundle 名。
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { RegisterAssetConfig } from "../config/RegisterAssetConfig";
|
|
52
|
+
import { RegisterLogic } from "../logic/RegisterLogic";
|
|
53
|
+
|
|
54
|
+
export class RegisterRegistry extends FW.Registry {
|
|
55
|
+
bundleName = "register";
|
|
56
|
+
logic: FW.Newable<FW.Logic> = RegisterLogic;
|
|
57
|
+
config: FW.Newable<FW.AssetConfig> = RegisterAssetConfig;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
FW.Framework.addRegistry("register", RegisterRegistry);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
规则:
|
|
64
|
+
|
|
65
|
+
- `Registry` 类名使用业务名 + `Registry`,例如 `RegisterRegistry`。
|
|
66
|
+
- `bundleName` 使用小写业务 bundle 名,例如 `"register"`。
|
|
67
|
+
- `logic/data/config/sender/handle` 字段必须显式声明为对应 `FW.Newable<...>` 类型。
|
|
68
|
+
- `FW.Framework.addRegistry("register", RegisterRegistry)` 必须与 `bundleName` 完全一致。
|
|
69
|
+
- 只声明实际存在的业务组件,不要为了占位声明空的 Data/Sender/Handle。
|
|
70
|
+
|
|
71
|
+
本文档是 Codex 在本项目中新增、修改业务功能时必须优先参考的工作规范。
|
|
72
|
+
|
|
73
|
+
## 首要约束
|
|
74
|
+
|
|
75
|
+
- 不修改 `assets/framework` 内部源码。
|
|
76
|
+
- 不把框架 README 当作唯一依据;以源码和 `docs/FRAMEWORK_*.md` 为准。
|
|
77
|
+
- 新业务功能优先扩展业务 bundle。
|
|
78
|
+
- 所有框架能力优先复用 `FW.Entry`、`FW.FrameworkBase`、`FW.LayerController`。
|
|
79
|
+
- UI 自动化优先配合 cocos-mcp 创建节点、绑定资源、保存 prefab 或场景。
|
|
80
|
+
|
|
81
|
+
## 开工前检查
|
|
82
|
+
|
|
83
|
+
Codex 在写代码前应先做:
|
|
84
|
+
|
|
85
|
+
1. 搜索目标 bundle 是否已存在。
|
|
86
|
+
2. 查找已有 `Registry`、`Logic`、`Data`、`AssetConfig`、`LayerController`。
|
|
87
|
+
3. 查找同类 UI 控制器的命名、目录、事件风格。
|
|
88
|
+
4. 查找资源路径和 prefab 命名。
|
|
89
|
+
5. 如果涉及 Cocos 场景/UI,先通过 cocos-mcp `scene_get_tree` 获取真实节点路径。
|
|
90
|
+
|
|
91
|
+
## 新增业务功能决策
|
|
92
|
+
|
|
93
|
+
### 用户要新增页面、弹窗、面板
|
|
94
|
+
|
|
95
|
+
执行:
|
|
96
|
+
|
|
97
|
+
1. 新增或复用 prefab。
|
|
98
|
+
2. 新增 `XxxLayerController extends FW.LayerController`。
|
|
99
|
+
3. 在 `AssetConfig` 中声明 prefab。
|
|
100
|
+
4. `layerAssetProperty` 返回该资源。
|
|
101
|
+
5. 使用 `FW.Entry.layerMgr.openAsync({ type: XxxLayerController, args })` 打开。
|
|
102
|
+
6. 事件用 `this.cc()`、`this.fw()`。
|
|
103
|
+
|
|
104
|
+
不要:
|
|
105
|
+
|
|
106
|
+
- 直接 `cc.instantiate(prefab)` 打开业务 UI。
|
|
107
|
+
- 直接在组件里 `node.on` 后不清理。
|
|
108
|
+
- 在构造函数里查节点。
|
|
109
|
+
|
|
110
|
+
### 用户要新增业务流程
|
|
111
|
+
|
|
112
|
+
执行:
|
|
113
|
+
|
|
114
|
+
1. 放入 `XxxLogic`。
|
|
115
|
+
2. 状态读写放入 `XxxData`。
|
|
116
|
+
3. 网络请求通过 `XxxSender`。
|
|
117
|
+
4. 网络返回通过 `XxxHandle` 写入 Data 或派发事件。
|
|
118
|
+
5. UI 监听事件刷新。
|
|
119
|
+
|
|
120
|
+
不要:
|
|
121
|
+
|
|
122
|
+
- 把网络请求写在 LayerController。
|
|
123
|
+
- 把 UI 节点保存到 Data。
|
|
124
|
+
|
|
125
|
+
### 用户要新增资源
|
|
126
|
+
|
|
127
|
+
执行:
|
|
128
|
+
|
|
129
|
+
1. 在 `XxxAssetConfig` 增加 `preLoad` 或 `demandLoad`。
|
|
130
|
+
2. 使用 `FW.Entry.resMgr.loadAsset()` 或 `loadAssetData()`。
|
|
131
|
+
3. 如果用于 Layer prefab,优先 `preLoad.prefab`。
|
|
132
|
+
|
|
133
|
+
不要:
|
|
134
|
+
|
|
135
|
+
- 在多个文件硬编码相同资源路径。
|
|
136
|
+
- 资源未加载就调用 `getAsset()`。
|
|
137
|
+
|
|
138
|
+
### 用户要新增 Socket 协议
|
|
139
|
+
|
|
140
|
+
执行:
|
|
141
|
+
|
|
142
|
+
1. 在 `Sender` 写发送方法。
|
|
143
|
+
2. 在 `Handle.onMessage()` 做协议分发。
|
|
144
|
+
3. 用 `FW.Entry.evtMgr.dispatch()` 通知业务。
|
|
145
|
+
4. 心跳识别实现 `onHeart()`。
|
|
146
|
+
5. 协议轮询实现 `getProtocolKey()`。
|
|
147
|
+
|
|
148
|
+
不要:
|
|
149
|
+
|
|
150
|
+
- 直接 new `WebSocket`。
|
|
151
|
+
- 在 UI 中解析所有网络消息。
|
|
152
|
+
|
|
153
|
+
## 必须复用的 API
|
|
154
|
+
|
|
155
|
+
| 场景 | 必须优先使用 |
|
|
156
|
+
| --- | --- |
|
|
157
|
+
| 打开 UI | `FW.Entry.layerMgr.openAsync/openSync` |
|
|
158
|
+
| 关闭 UI | `ctr.close()` 或 `FW.Entry.layerMgr.close(ctr)` |
|
|
159
|
+
| 查节点 | `ctr.find()` 或 `FW.Entry.uiMgr.find()` |
|
|
160
|
+
| 按钮事件 | `ctr.cc()` 或 `ctr.registerEvent()` |
|
|
161
|
+
| 全局事件 | `FW.Entry.evtMgr.register/dispatch` |
|
|
162
|
+
| 资源加载 | `FW.Entry.resMgr` |
|
|
163
|
+
| 定时器 | `FW.Entry.timeMgr` |
|
|
164
|
+
| 异步重试/取消 | `FW.Entry.promiseMgr` 或 `FrameworkBase.invoke()` |
|
|
165
|
+
| 对象复用 | `FW.Entry.objectMgr.createObjectPool()` |
|
|
166
|
+
| 日志 | `FW.Log.debug/warn/error/...` |
|
|
167
|
+
| 业务依赖 | `this.getLogic/getData/getConfig/getSender/getHandle` |
|
|
168
|
+
|
|
169
|
+
## 代码风格
|
|
170
|
+
|
|
171
|
+
必须:
|
|
172
|
+
|
|
173
|
+
- 类名使用业务名前缀和框架后缀。
|
|
174
|
+
- 继承对应框架基类。
|
|
175
|
+
- 控制器使用 `private` 方法拆分 `cacheNodes()`、`bindEvents()`、`render()`。
|
|
176
|
+
- 异步方法处理 `undefined` 返回。
|
|
177
|
+
- 用 `FW.Log` 记录业务错误。
|
|
178
|
+
- UI 事件设置合理 `responseInterval`,默认 500ms 已由 `LayerController` 提供。
|
|
179
|
+
|
|
180
|
+
避免:
|
|
181
|
+
|
|
182
|
+
- 在一个方法里混合资源加载、网络请求、UI 渲染、数据变更。
|
|
183
|
+
- 使用魔法字符串事件名散落各处;大型功能应集中定义事件常量。
|
|
184
|
+
- 同一资源路径在多个文件重复。
|
|
185
|
+
- 在 `onDestroy` 外留下未清理定时器和事件。
|
|
186
|
+
|
|
187
|
+
## cocos-mcp 工作流
|
|
188
|
+
|
|
189
|
+
当任务涉及 UI 自动化:
|
|
190
|
+
|
|
191
|
+
1. 调用 `cocos_mcp_diagnose` 检查连接和当前场景。
|
|
192
|
+
2. 调用 `scene_get_tree({ includeDiagnostics: true })` 获取节点路径。
|
|
193
|
+
3. 如果要绑定真实资源,先用 `asset_query` 或 `asset_resolve` 获取准确资源。
|
|
194
|
+
4. 创建大结构用 `ui_create_tree`,小改动用 `ui_create_node`、`ui_set_node_props`、`ui_add_component`。
|
|
195
|
+
5. 设置 SpriteFrame 用 `ui_set_sprite_frame`,不要猜 uuid。
|
|
196
|
+
6. 创建 prefab 用 `prefab_create_from_tree` 或 `prefab_create_from_node`。
|
|
197
|
+
7. 绑定按钮只在脚本组件和 handler 已存在时使用 `ui_bind_button_event`;否则让 `LayerController.cc()` 在代码中绑定。
|
|
198
|
+
8. 完成后用 `scene_get_tree` 验证节点。
|
|
199
|
+
9. 用户确认需要保存时调用 `scene_save`。
|
|
200
|
+
|
|
201
|
+
## UI 自动化注意事项
|
|
202
|
+
|
|
203
|
+
- MCP 节点路径必须是绝对路径,如 `/Canvas/ShopLayer/CloseButton`。
|
|
204
|
+
- 不要随机选择同名资源;如果 `asset_resolve` 返回 ambiguous,必须让用户或上下文消歧。
|
|
205
|
+
- 创建 UI 前确认 Canvas 和目标父节点存在。
|
|
206
|
+
- 如果生成框架 Layer prefab,根节点应挂 `FW.Layer` 对应组件名,且 prefab 名应与 `layerAssetProperty.path` 对齐。
|
|
207
|
+
- UI 代码中的节点名必须和 MCP 创建的节点名一致。
|
|
208
|
+
|
|
209
|
+
## 完成前验证
|
|
210
|
+
|
|
211
|
+
Codex 完成改动后应检查:
|
|
212
|
+
|
|
213
|
+
- 没有修改 `assets/framework`。
|
|
214
|
+
- 新业务类名满足注入约定。
|
|
215
|
+
- `AssetConfig` 资源路径和 prefab 实际路径一致。
|
|
216
|
+
- LayerController 的 `layerAssetProperty` 不为空。
|
|
217
|
+
- 事件和定时器有生命周期清理。
|
|
218
|
+
- TypeScript 没有明显类型错误。
|
|
219
|
+
- 如果用 MCP 创建 UI,真实场景树里节点存在。
|