cocos2d-cli 1.4.0 → 1.5.0

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.
Files changed (45) hide show
  1. package/README.md +142 -0
  2. package/bin/cocos2d-cli.js +21 -12
  3. package/package.json +1 -1
  4. package/src/commands/add-component.js +77 -85
  5. package/src/commands/add.js +116 -212
  6. package/src/commands/create-scene.js +128 -109
  7. package/src/commands/get.js +113 -18
  8. package/src/commands/prefab-create.js +43 -139
  9. package/src/commands/remove-component.js +111 -0
  10. package/src/commands/remove.js +59 -122
  11. package/src/commands/set.js +121 -36
  12. package/src/commands/tree.js +3 -8
  13. package/src/lib/cc/CCButton.js +122 -0
  14. package/src/lib/cc/CCCamera.js +93 -0
  15. package/src/lib/cc/CCCanvas.js +64 -0
  16. package/src/lib/cc/CCColor.js +32 -0
  17. package/src/lib/cc/CCComponent.js +60 -0
  18. package/src/lib/cc/CCLabel.js +109 -0
  19. package/src/lib/cc/CCNode.js +242 -0
  20. package/src/lib/cc/CCObject.js +23 -0
  21. package/src/lib/cc/CCPrefab.js +242 -0
  22. package/src/lib/cc/CCRect.js +32 -0
  23. package/src/lib/cc/CCScene.js +42 -0
  24. package/src/lib/cc/CCSceneAsset.js +271 -0
  25. package/src/lib/cc/CCSize.js +26 -0
  26. package/src/lib/cc/CCSprite.js +82 -0
  27. package/src/lib/cc/CCTrs.js +74 -0
  28. package/src/lib/cc/CCVec2.js +26 -0
  29. package/src/lib/cc/CCVec3.js +29 -0
  30. package/src/lib/cc/CCWidget.js +98 -0
  31. package/src/lib/cc/index.js +40 -0
  32. package/src/lib/fire-utils.js +1 -1
  33. package/src/lib/json-parser.js +166 -0
  34. package/src/lib/node-utils.js +64 -28
  35. package/src/lib/templates.js +31 -194
  36. package/src/lib/utils.js +63 -0
  37. package/src/lib/components/button.js +0 -137
  38. package/src/lib/components/camera.js +0 -107
  39. package/src/lib/components/canvas.js +0 -89
  40. package/src/lib/components/index.js +0 -157
  41. package/src/lib/components/label.js +0 -120
  42. package/src/lib/components/layout.js +0 -110
  43. package/src/lib/components/particle-system.js +0 -160
  44. package/src/lib/components/sprite.js +0 -98
  45. package/src/lib/components/widget.js +0 -122
package/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # cocos2d-cli
2
+
3
+ Cocos Creator 场景/预制体命令行操作工具,支持通过 CLI 或 AI 自动化创建和编辑游戏界面。
4
+
5
+ ## 功能
6
+
7
+ - 创建场景和预制体
8
+ - 添加/删除节点和组件
9
+ - 修改节点和组件属性
10
+ - 查看节点树结构
11
+ - 从简化 JSON 创建复杂界面
12
+
13
+ ## 安装
14
+
15
+ ```bash
16
+ npm install -g cocos2d-cli
17
+ ```
18
+
19
+ ## 使用
20
+
21
+ ```bash
22
+ cocos2d-cli help # 查看帮助
23
+ cocos2d-cli --help # 同上
24
+ ```
25
+
26
+ ### 创建预制体
27
+
28
+ ### 创建预制体
29
+
30
+ ```bash
31
+ # 创建空预制体
32
+ cocos2d-cli create-prefab ./MyPrefab.prefab
33
+
34
+ # 从 JSON 创建预制体
35
+ cocos2d-cli create-prefab ./ui.json ./MyPrefab.prefab
36
+ ```
37
+
38
+ ### 创建场景
39
+
40
+ ```bash
41
+ # 创建默认场景(含 Canvas 和 Main Camera)
42
+ cocos2d-cli create-scene ./MyScene.fire
43
+
44
+ # 从 JSON 创建场景
45
+ cocos2d-cli create-scene ./ui.json ./MyScene.fire
46
+ ```
47
+
48
+ ### 节点操作
49
+
50
+ ```bash
51
+ # 添加节点
52
+ cocos2d-cli add ./MyPrefab.prefab Root NewNode --type=sprite --width=100 --height=100
53
+
54
+ # 删除节点
55
+ cocos2d-cli remove ./MyPrefab.prefab Root/NewNode
56
+
57
+ # 查看节点树
58
+ cocos2d-cli tree ./MyPrefab.prefab
59
+ ```
60
+
61
+ ### 组件操作
62
+
63
+ ```bash
64
+ # 添加组件
65
+ cocos2d-cli add-component ./MyPrefab.prefab Root label
66
+
67
+ # 删除组件
68
+ cocos2d-cli remove-component ./MyPrefab.prefab Root label
69
+ ```
70
+
71
+ ### 属性操作
72
+
73
+ ```bash
74
+ # 获取属性
75
+ cocos2d-cli get ./MyPrefab.prefab Root width
76
+ cocos2d-cli get ./MyPrefab.prefab Root label.string
77
+
78
+ # 设置属性
79
+ cocos2d-cli set ./MyPrefab.prefab Root width 200
80
+ cocos2d-cli set ./MyPrefab.prefab Root label.string "Hello"
81
+ ```
82
+
83
+ ## 简化 JSON 格式
84
+
85
+ AI 可以通过简化 JSON 描述界面结构:
86
+
87
+ ```json
88
+ {
89
+ "name": "MyButton",
90
+ "width": 200,
91
+ "height": 60,
92
+ "components": ["sprite", "button"],
93
+ "children": [
94
+ {
95
+ "name": "Label",
96
+ "components": [
97
+ {
98
+ "type": "label",
99
+ "string": "Click Me",
100
+ "fontSize": 24
101
+ }
102
+ ]
103
+ }
104
+ ]
105
+ }
106
+ ```
107
+
108
+ ### 支持的组件类型
109
+
110
+ - `canvas` - Canvas
111
+ - `widget` - Widget
112
+ - `sprite` - Sprite
113
+ - `label` - Label
114
+ - `button` - Button
115
+ - `camera` - Camera
116
+
117
+ ### 节点属性
118
+
119
+ | 属性 | 说明 |
120
+ |------|------|
121
+ | `name` | 节点名称 |
122
+ | `active` | 是否激活 |
123
+ | `x`, `y` | 位置 |
124
+ | `width`, `height` | 尺寸 |
125
+ | `scaleX`, `scaleY` | 缩放 |
126
+ | `rotation` | 旋转角度 |
127
+ | `anchorX`, `anchorY` | 锚点 |
128
+ | `opacity` | 透明度 |
129
+ | `color` | 颜色 (十六进制如 "#ff0000") |
130
+
131
+ ## 架构
132
+
133
+ ```
134
+ 输入 内存模型 输出
135
+ ───── ──────── ─────
136
+ 简化JSON ──→ json-parser ──→ CCNode树 ─┬─→ CCSceneAsset ──→ .fire
137
+ 编辑器文件 ──→ fromJSON ──→ CC对象树 ──┘─→ CCPrefab ──→ .prefab
138
+ ```
139
+
140
+ ## License
141
+
142
+ MIT
@@ -13,6 +13,7 @@ const commands = {
13
13
  set: '../src/commands/set',
14
14
  add: '../src/commands/add',
15
15
  'add-component': '../src/commands/add-component',
16
+ 'remove-component': '../src/commands/remove-component',
16
17
  'remove': '../src/commands/remove',
17
18
  build: '../src/commands/build',
18
19
  'create-prefab': '../src/commands/prefab-create',
@@ -28,15 +29,21 @@ Cocos Creator CLI - 场景/预制体操作工具集
28
29
  cocos2d-cli <command> [options]
29
30
 
30
31
  命令:
31
- tree <场景.fire | 预制体.prefab> 查看节点树(获取索引)
32
- get <场景.fire | 预制体.prefab> <索引> 获取节点属性
33
- set <场景.fire | 预制体.prefab> <索引> [选项] 修改节点属性
34
- add <场景.fire | 预制体.prefab> <父索引> <名称> 添加节点
35
- add-component <文件> <节点索引> <类型> 给节点添加组件
36
- remove <文件> <索引> [--component|--node] 删除节点或组件(自动检测类型)
32
+ tree <场景.fire | 预制体.prefab> 查看节点树
33
+ get <场景.fire | 预制体.prefab> <节点路径> 获取节点属性
34
+ set <场景.fire | 预制体.prefab> <节点路径> [选项] 修改节点属性
35
+ add <场景.fire | 预制体.prefab> <父节点路径> <名称> 添加节点
36
+ add-component <文件> <节点路径> <类型> 给节点添加组件
37
+ remove-component <文件> <节点路径> <类型> 删除节点组件
38
+ remove <文件> <节点路径> 删除节点
37
39
  build <项目目录> 构建组件映射
38
40
  create-prefab [JSON文件] <输出.prefab> 创建预制体(不传JSON则创建默认)
39
- create-scene <JSON文件> <输出.fire> JSON文件创建场景
41
+ create-scene [JSON文件] <输出.fire> 创建场景(不传JSON则创建默认)
42
+
43
+ 节点路径格式:
44
+ Canvas - 根节点下的 Canvas
45
+ Canvas/MidNode - Canvas 下的 MidNode
46
+ Canvas/GameScene/NodeA - 多层嵌套路径
40
47
 
41
48
  选项:
42
49
  --name=<名称> 修改节点名称
@@ -56,7 +63,6 @@ Cocos Creator CLI - 场景/预制体操作工具集
56
63
  --fontSize=<数值> 修改 Label 字体大小
57
64
  --lineHeight=<数值> 修改 Label 行高
58
65
  --type=sprite/label/button 添加节点时指定组件类型
59
- --at=<索引> 添加节点时插入到子节点的指定位置(0=第一个)
60
66
 
61
67
  JSON 格式 (create-prefab / create-scene):
62
68
  {
@@ -98,9 +104,12 @@ JSON 格式 (create-prefab / create-scene):
98
104
 
99
105
  示例:
100
106
  cocos2d-cli tree assets/main.fire
101
- cocos2d-cli get assets/main.fire 5
102
- cocos2d-cli set assets/main.fire 8 --x=100 --y=200 --color=#ff0000
103
- cocos2d-cli add assets/main.fire 5 NewSprite --type=sprite --x=100
107
+ cocos2d-cli get assets/main.fire Canvas/MidNode
108
+ cocos2d-cli set assets/main.fire Canvas/MidNode --x=100 --y=200 --color=#ff0000
109
+ cocos2d-cli add assets/main.fire Canvas NewSprite --type=sprite --x=100
110
+ cocos2d-cli add-component assets/main.fire Canvas/MidNode label
111
+ cocos2d-cli remove-component assets/main.fire Canvas/MidNode label
112
+ cocos2d-cli remove assets/main.fire Canvas/MidNode
104
113
 
105
114
  # 从 JSON 文件创建场景
106
115
  cocos2d-cli create-scene scene.json assets/scene.fire
@@ -116,7 +125,7 @@ JSON 格式 (create-prefab / create-scene):
116
125
  // 解析参数
117
126
  const args = process.argv.slice(2);
118
127
 
119
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
128
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
120
129
  showHelp();
121
130
  process.exit(0);
122
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cocos2d-cli",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Command-line tools for AI to read and manipulate Cocos Creator 2.4.x project scenes",
5
5
  "main": "bin/cocos2d-cli.js",
6
6
  "bin": {
@@ -1,119 +1,111 @@
1
1
  /**
2
- * add-component 命令 - 给已存在的节点添加组件
2
+ * add-component 命令 - 添加组件
3
3
  */
4
4
 
5
- const { loadScene, saveScene, buildMaps, findNodeIndex, refreshEditor } = require('../lib/fire-utils');
6
- const { outputError, outputSuccess, generateId } = require('../lib/utils');
7
- const { createComponent } = require('../lib/components');
8
- const fs = require('fs');
9
5
  const path = require('path');
6
+ const fs = require('fs');
7
+ const { CCSceneAsset, CCPrefab, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton, CCCamera } = require('../lib/cc');
8
+ const { buildTree } = require('../lib/node-utils');
9
+ const { loadScriptMap, isPrefab } = require('../lib/fire-utils');
10
10
 
11
- // 加载脚本映射
12
- function loadScriptMap(projectPath) {
13
- const mapPath = path.join(projectPath, 'data', 'script_map.json');
14
- try {
15
- if (fs.existsSync(mapPath)) {
16
- return JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
17
- }
18
- } catch (e) {}
19
- return {};
11
+ /**
12
+ * 创建组件
13
+ */
14
+ function createComponent(type) {
15
+ switch (type.toLowerCase()) {
16
+ case 'canvas': return new CCCanvas();
17
+ case 'widget': return new CCWidget();
18
+ case 'sprite': return new CCSprite();
19
+ case 'label': return new CCLabel();
20
+ case 'button': return new CCButton();
21
+ case 'camera': return new CCCamera();
22
+ default: return null;
23
+ }
20
24
  }
21
25
 
22
- // 创建自定义脚本组件
23
- function createScriptComponent(scriptUuid, nodeId, scriptMap) {
24
- const scriptInfo = scriptMap[scriptUuid];
25
- const typeName = scriptInfo ? scriptInfo.name : scriptUuid;
26
+ /**
27
+ * 查找节点
28
+ */
29
+ function findNode(root, path) {
30
+ if (!path) return root;
31
+
32
+ const parts = path.split('/').filter(p => p);
33
+ if (parts.length === 0) return root;
34
+
35
+ let current = root;
26
36
 
27
- return {
28
- "__type__": typeName,
29
- "_name": "",
30
- "_objFlags": 0,
31
- "node": { "__id__": nodeId },
32
- "_enabled": true,
33
- "_id": generateId()
34
- };
37
+ if (parts[0] === root._name) {
38
+ parts.shift();
39
+ }
40
+
41
+ for (const part of parts) {
42
+ if (!current._children || current._children.length === 0) return null;
43
+ const found = current._children.find(c => c._name === part);
44
+ if (!found) return null;
45
+ current = found;
46
+ }
47
+
48
+ return current;
35
49
  }
36
50
 
37
51
  function run(args) {
38
52
  if (args.length < 3) {
39
- outputError('用法: cocos2d-cli add-component <场景文件路径> <节点路径> <组件类型>');
53
+ console.log(JSON.stringify({ error: '用法: cocos2d-cli add-component <场景.fire|预制体.prefab> <节点路径> <组件类型>' }));
40
54
  return;
41
55
  }
42
56
 
43
- const scenePath = args[0];
44
- const nodeRef = args[1];
45
- const componentType = args[2];
57
+ const filePath = args[0];
58
+ const nodePath = args[1];
59
+ const compType = args[2];
60
+
61
+ const ext = path.extname(filePath).toLowerCase();
46
62
 
47
63
  try {
48
- const data = loadScene(scenePath);
49
- const { indexMap } = buildMaps(data);
64
+ let root;
65
+ let asset;
66
+ const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
50
67
 
51
- const nodeIndex = findNodeIndex(data, indexMap, nodeRef);
52
-
53
- if (nodeIndex === null || !data[nodeIndex]) {
54
- outputError(`找不到节点: ${nodeRef}`);
68
+ if (ext === '.fire') {
69
+ asset = CCSceneAsset.fromJSON(json);
70
+ root = asset._scene;
71
+ } else if (ext === '.prefab') {
72
+ asset = CCPrefab.fromJSON(json);
73
+ root = asset._root;
74
+ } else {
75
+ console.log(JSON.stringify({ error: '不支持的文件类型,仅支持 .fire 和 .prefab' }));
55
76
  return;
56
77
  }
57
78
 
58
- const node = data[nodeIndex];
59
-
60
- // 检查是否已有该类型组件
61
- const ccType = 'cc.' + componentType.charAt(0).toUpperCase() + componentType.slice(1);
62
- const existingComp = node._components?.find(comp => {
63
- const compData = data[comp.__id__];
64
- if (!compData) return false;
65
- const compType = compData.__type__;
66
- return compType === componentType || compType === ccType;
67
- });
79
+ const node = findNode(root, nodePath);
68
80
 
69
- if (existingComp) {
70
- outputError(`节点 "${node._name}" 已有 ${componentType} 组件`);
81
+ if (!node) {
82
+ console.log(JSON.stringify({ error: `节点不存在: ${nodePath}` }));
71
83
  return;
72
84
  }
73
85
 
74
- const compIndex = data.length;
75
- let componentData;
76
-
77
- // 尝试使用内置组件
78
- componentData = createComponent(componentType, nodeIndex);
79
-
80
- if (!componentData) {
81
- // 自定义脚本组件
82
- const projectPath = path.dirname(scenePath);
83
- const scriptMap = loadScriptMap(projectPath);
84
-
85
- let scriptUuid = null;
86
- for (const [uuid, info] of Object.entries(scriptMap)) {
87
- if (info.name === componentType) {
88
- scriptUuid = uuid;
89
- break;
90
- }
91
- }
92
-
93
- const uuidRegex = /^[a-f0-9-]{36}$/i;
94
- if (!scriptUuid && uuidRegex.test(componentType)) {
95
- scriptUuid = componentType;
96
- }
97
-
98
- componentData = createScriptComponent(scriptUuid || componentType, nodeIndex, scriptMap);
86
+ // 创建组件
87
+ const comp = createComponent(compType);
88
+ if (!comp) {
89
+ console.log(JSON.stringify({ error: `不支持的组件类型: ${compType}` }));
90
+ return;
99
91
  }
100
92
 
101
- data.push(componentData);
93
+ comp.node = node;
94
+ node._components = node._components || [];
95
+ node._components.push(comp);
102
96
 
103
- if (!node._components) node._components = [];
104
- node._components.push({ "__id__": compIndex });
97
+ // 保存
98
+ const data = asset.toJSON();
99
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
105
100
 
106
- saveScene(scenePath, data);
107
- refreshEditor(scenePath);
101
+ // 输出节点树
102
+ const scriptMap = loadScriptMap(filePath);
103
+ const prefab = isPrefab(data);
104
+ const startIndex = prefab ? 0 : 1;
105
+ console.log(buildTree(data, scriptMap, startIndex).trim());
108
106
 
109
- outputSuccess({
110
- componentIndex: compIndex,
111
- componentType: componentData.__type__,
112
- nodeIndex,
113
- nodeName: node._name
114
- });
115
107
  } catch (err) {
116
- outputError(err.message);
108
+ console.log(JSON.stringify({ error: err.message }));
117
109
  }
118
110
  }
119
111