cocos2d-cli 1.4.0 → 1.5.1

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 (47) 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 +133 -109
  7. package/src/commands/get.js +113 -18
  8. package/src/commands/prefab-create.js +49 -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 +75 -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/data/prefab-template.json +0 -72
  38. package/data/scene-template.json +0 -241
  39. package/src/lib/components/button.js +0 -137
  40. package/src/lib/components/camera.js +0 -107
  41. package/src/lib/components/canvas.js +0 -89
  42. package/src/lib/components/index.js +0 -157
  43. package/src/lib/components/label.js +0 -120
  44. package/src/lib/components/layout.js +0 -110
  45. package/src/lib/components/particle-system.js +0 -160
  46. package/src/lib/components/sprite.js +0 -98
  47. package/src/lib/components/widget.js +0 -122
@@ -1,75 +1,120 @@
1
1
  /**
2
- * create-scene 命令 - 从 JSON 结构创建场景文件
2
+ * create-scene 命令 - 创建场景文件
3
3
  */
4
4
 
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
- const { outputError, outputSuccess } = require('../lib/utils');
8
- const { createNodeData } = require('../lib/node-utils');
9
- const { parseComponent, createComponent, applyComponentProps } = require('../lib/components');
10
- const { createScene } = require('../lib/templates');
7
+ const { CCNode, CCScene, CCSceneAsset, CCCanvas, CCWidget, CCCamera } = require('../lib/cc');
8
+ const { buildTree } = require('../lib/node-utils');
9
+ const { loadScriptMap, createSceneMeta, saveMetaFile } = require('../lib/fire-utils');
10
+ const { generateUUID, generateCompressedUUID } = require('../lib/utils');
11
+ const { fromJSON } = require('../lib/json-parser');
11
12
 
12
13
  /**
13
- * 从 JSON 定义创建场景数据
14
+ * 从项目配置读取设计分辨率
14
15
  */
15
- function createSceneData(nodeDefs, sceneName) {
16
- const data = createScene(sceneName);
16
+ function getDesignResolution(outputPath) {
17
+ const defaultResolution = { width: 960, height: 640 };
17
18
 
18
- // Canvas 节点索引
19
- const canvasIndex = 2;
20
-
21
- // 支持数组或单个节点
22
- const nodes = Array.isArray(nodeDefs) ? nodeDefs : [nodeDefs];
19
+ let currentDir = path.dirname(path.resolve(outputPath));
20
+ while (currentDir !== path.dirname(currentDir)) {
21
+ const settingsPath = path.join(currentDir, 'settings', 'project.json');
22
+ if (fs.existsSync(settingsPath)) {
23
+ try {
24
+ const config = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
25
+ if (config['design-resolution-width'] && config['design-resolution-height']) {
26
+ return {
27
+ width: config['design-resolution-width'],
28
+ height: config['design-resolution-height']
29
+ };
30
+ }
31
+ } catch (e) {}
32
+ }
33
+ currentDir = path.dirname(currentDir);
34
+ }
23
35
 
24
- // 添加用户节点到 Canvas
25
- for (const nodeDef of nodes) {
26
- addUserNode(data, nodeDef, canvasIndex);
36
+ return defaultResolution;
37
+ }
38
+
39
+ /**
40
+ * 从 meta 文件读取 uuid
41
+ */
42
+ function readUuidFromMeta(scenePath) {
43
+ const metaPath = scenePath + '.meta';
44
+ if (fs.existsSync(metaPath)) {
45
+ try {
46
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
47
+ return meta.uuid || null;
48
+ } catch (e) {
49
+ return null;
50
+ }
27
51
  }
52
+ return null;
53
+ }
28
54
 
29
- return data;
55
+ /**
56
+ * 为节点树设置 _id
57
+ */
58
+ function setNodeId(node) {
59
+ node._id = generateCompressedUUID();
60
+ if (node._children) {
61
+ node._children.forEach(child => setNodeId(child));
62
+ }
30
63
  }
31
64
 
32
65
  /**
33
- * 添加用户节点
66
+ * 创建默认场景结构(Canvas + Main Camera)
34
67
  */
35
- function addUserNode(data, def, parentIndex) {
36
- const nodeIndex = data.length;
37
- const node = createNodeData(def.name || 'Node', parentIndex, def);
68
+ function createDefaultScene(asset, resolution) {
69
+ const { width, height } = resolution;
70
+ const scene = asset._scene;
38
71
 
39
- data.push(node);
72
+ // 创建 Canvas 节点
73
+ const canvas = new CCNode('Canvas');
74
+ canvas._contentSize.width = width;
75
+ canvas._contentSize.height = height;
76
+ canvas._anchorPoint.x = 0.5;
77
+ canvas._anchorPoint.y = 0.5;
78
+ canvas._trs.array[0] = width / 2;
79
+ canvas._trs.array[1] = height / 2;
80
+ canvas._is3DNode = false;
81
+ canvas._id = generateCompressedUUID();
40
82
 
41
- // 添加组件
42
- if (def.components) {
43
- for (const compDef of def.components) {
44
- const parsed = parseComponent(compDef);
45
- if (parsed) {
46
- const comp = createComponent(parsed.type, nodeIndex);
47
- if (comp) {
48
- applyComponentProps(comp, parsed.props, node);
49
- data.push(comp);
50
- node._components.push({ "__id__": data.length - 1 });
51
- }
52
- }
53
- }
54
- }
83
+ // Canvas 组件
84
+ const canvasComp = new CCCanvas();
85
+ canvasComp.setDesignResolution(width, height);
86
+ canvasComp.node = canvas;
55
87
 
56
- // 更新父节点的 _children
57
- data[parentIndex]._children.push({ "__id__": nodeIndex });
88
+ // Widget 组件
89
+ const widget = new CCWidget();
90
+ widget.node = canvas;
58
91
 
59
- // 递归处理子节点
60
- if (def.children && def.children.length > 0) {
61
- for (const childDef of def.children) {
62
- addUserNode(data, childDef, nodeIndex);
63
- }
64
- }
92
+ canvas._components = [canvasComp, widget];
93
+ canvas._parent = scene;
94
+ scene._children = [canvas];
95
+
96
+ // 创建 Main Camera 节点
97
+ const camera = new CCNode('Main Camera');
98
+ camera._contentSize.width = 0;
99
+ camera._contentSize.height = 0;
100
+ camera._anchorPoint.x = 0.5;
101
+ camera._anchorPoint.y = 0.5;
102
+ camera._is3DNode = false;
103
+ camera._id = generateCompressedUUID();
104
+
105
+ // Camera 组件
106
+ const cameraComp = new CCCamera();
107
+ cameraComp.node = camera;
108
+
109
+ camera._components = [cameraComp];
110
+ camera._parent = canvas;
111
+ canvas._children = [camera];
65
112
  }
66
113
 
67
114
  function run(args) {
68
115
  if (args.length < 1) {
69
- outputError({
70
- message: '用法: cocos2d-cli create-scene [JSON文件路径] <输出路径.fire>',
71
- hint: '不传 JSON 则创建默认场景'
72
- });
116
+ console.log(JSON.stringify({ error: '用法: cocos2d-cli create-scene [JSON文件路径] <输出路径.fire>' }));
117
+ console.log(JSON.stringify({ hint: '不传 JSON 则创建默认场景(含 Canvas 和 Main Camera)' }));
73
118
  return;
74
119
  }
75
120
 
@@ -85,77 +130,56 @@ function run(args) {
85
130
 
86
131
  const sceneName = path.basename(outputPath, '.fire');
87
132
 
88
- // 没有传 JSON,创建默认场景
89
- if (!jsonPath) {
90
- try {
91
- if (fs.existsSync(outputPath)) {
92
- outputError(`文件已存在: ${outputPath}`);
93
- return;
94
- }
95
-
96
- const dir = path.dirname(outputPath);
97
- if (!fs.existsSync(dir)) {
98
- fs.mkdirSync(dir, { recursive: true });
99
- }
100
-
101
- const data = createScene(sceneName);
102
- fs.writeFileSync(outputPath, JSON.stringify(data, null, 2), 'utf8');
133
+ try {
134
+ // 创建场景
135
+ const asset = new CCSceneAsset();
136
+ const scene = new CCScene(sceneName);
137
+ asset._scene = scene;
138
+ scene._children = [];
139
+
140
+ // 从 JSON 创建
141
+ if (jsonPath && fs.existsSync(jsonPath)) {
142
+ const input = fs.readFileSync(jsonPath, 'utf8');
143
+ const nodeDef = JSON.parse(input.replace(/^\uFEFF/, '').trim());
103
144
 
104
- let nodeCount = 0, compCount = 0;
105
- for (const item of data) {
106
- if (item.__type__ === 'cc.Node') nodeCount++;
107
- else if (item.__type__?.startsWith('cc.') && !['cc.Scene', 'cc.SceneAsset'].includes(item.__type__)) {
108
- compCount++;
109
- }
145
+ const nodes = Array.isArray(nodeDef) ? nodeDef : [nodeDef];
146
+ for (const def of nodes) {
147
+ const node = fromJSON(def);
148
+ setNodeId(node);
149
+ node._parent = scene;
150
+ scene._children.push(node);
110
151
  }
111
-
112
- outputSuccess({
113
- path: outputPath,
114
- nodes: nodeCount,
115
- components: compCount
116
- });
117
- return;
118
- } catch (err) {
119
- outputError(err.message);
120
- return;
152
+ } else {
153
+ // 没有 JSON,创建默认场景结构
154
+ const resolution = getDesignResolution(outputPath);
155
+ createDefaultScene(asset, resolution);
121
156
  }
122
- }
123
-
124
- if (!fs.existsSync(jsonPath)) {
125
- outputError(`JSON 文件不存在: ${jsonPath}`);
126
- return;
127
- }
128
157
 
129
- try {
130
- const input = fs.readFileSync(jsonPath, 'utf8');
131
- const cleanInput = input.replace(/^\uFEFF/, '').trim();
132
- const nodeDef = JSON.parse(cleanInput);
133
-
134
- const sceneData = createSceneData(nodeDef, sceneName);
135
-
136
- const outputDir = path.dirname(outputPath);
137
- if (!fs.existsSync(outputDir)) {
138
- fs.mkdirSync(outputDir, { recursive: true });
158
+ // 确保目录存在
159
+ const dir = path.dirname(outputPath);
160
+ if (!fs.existsSync(dir)) {
161
+ fs.mkdirSync(dir, { recursive: true });
139
162
  }
140
163
 
141
- fs.writeFileSync(outputPath, JSON.stringify(sceneData, null, 2), 'utf8');
142
-
143
- let nodeCount = 0, compCount = 0;
144
- for (const item of sceneData) {
145
- if (item.__type__ === 'cc.Node') nodeCount++;
146
- else if (item.__type__?.startsWith('cc.') && !['cc.Scene', 'cc.SceneAsset'].includes(item.__type__)) {
147
- compCount++;
148
- }
164
+ // 设置 Scene._id
165
+ const uuid = readUuidFromMeta(outputPath);
166
+ scene._id = uuid || generateUUID();
167
+
168
+ // 保存
169
+ const data = asset.toJSON();
170
+ fs.writeFileSync(outputPath, JSON.stringify(data, null, 2), 'utf8');
171
+
172
+ // 生成并保存 meta 文件(如果不存在)
173
+ if (!uuid) {
174
+ saveMetaFile(outputPath, createSceneMeta(scene._id));
149
175
  }
150
176
 
151
- outputSuccess({
152
- path: outputPath,
153
- nodes: nodeCount,
154
- components: compCount
155
- });
177
+ // 输出 tree
178
+ const scriptMap = loadScriptMap(outputPath);
179
+ console.log(buildTree(data, scriptMap, 1).trim());
156
180
 
157
181
  } catch (err) {
158
- outputError(err.message);
182
+ console.log(JSON.stringify({ error: err.message }));
159
183
  }
160
184
  }
161
185
 
@@ -1,38 +1,133 @@
1
1
  /**
2
- * get 命令 - 获取节点信息
2
+ * get 命令 - 获取节点或组件属性
3
3
  */
4
4
 
5
- const { loadScene, buildMaps, findNodeIndex } = require('../lib/fire-utils');
6
- const { getNodeState } = require('../lib/node-utils');
5
+ const path = require('path');
6
+ const fs = require('fs');
7
+ const { CCSceneAsset, CCPrefab } = require('../lib/cc');
8
+
9
+ /**
10
+ * 查找节点
11
+ */
12
+ function findNode(root, path) {
13
+ if (!path) return root;
14
+
15
+ const parts = path.split('/').filter(p => p);
16
+ if (parts.length === 0) return root;
17
+
18
+ let current = root;
19
+
20
+ if (parts[0] === root._name) {
21
+ parts.shift();
22
+ }
23
+
24
+ for (const part of parts) {
25
+ if (!current._children || current._children.length === 0) return null;
26
+ const found = current._children.find(c => c._name === part);
27
+ if (!found) return null;
28
+ current = found;
29
+ }
30
+
31
+ return current;
32
+ }
33
+
34
+ /**
35
+ * 查找组件
36
+ */
37
+ function findComponent(node, compType) {
38
+ if (!node._components) return null;
39
+
40
+ const type = compType.toLowerCase();
41
+ const typeName = 'cc.' + type.charAt(0).toUpperCase() + type.slice(1);
42
+
43
+ return node._components.find(c => c.__type__ === typeName);
44
+ }
45
+
46
+ /**
47
+ * 获取节点属性值
48
+ */
49
+ function getNodeProp(node, prop) {
50
+ switch (prop.toLowerCase()) {
51
+ case 'name': return node._name;
52
+ case 'active': return node._active;
53
+ case 'x': return node._trs.array[0];
54
+ case 'y': return node._trs.array[1];
55
+ case 'width': return node._contentSize.width;
56
+ case 'height': return node._contentSize.height;
57
+ case 'scalex': return node._trs.array[7];
58
+ case 'scaley': return node._trs.array[8];
59
+ case 'rotation': return node._eulerAngles.z;
60
+ case 'anchorx': return node._anchorPoint.x;
61
+ case 'anchory': return node._anchorPoint.y;
62
+ case 'opacity': return node._opacity;
63
+ case 'color': return node._color;
64
+ default: return undefined;
65
+ }
66
+ }
7
67
 
8
68
  function run(args) {
9
- if (args.length < 2) {
10
- console.log(JSON.stringify({ error: '用法: cocos2d-cli get <场景.fire | 预制体.prefab> <节点索引|名称>' }));
69
+ if (args.length < 3) {
70
+ console.log(JSON.stringify({ error: '用法: cocos2d-cli get <场景.fire|预制体.prefab> <节点路径> <属性名|组件.属性>' }));
11
71
  return;
12
72
  }
13
73
 
14
- const scenePath = args[0];
15
- const nodeRef = args[1];
74
+ const filePath = args[0];
75
+ const nodePath = args[1];
76
+ const propPath = args[2];
77
+
78
+ const ext = path.extname(filePath).toLowerCase();
16
79
 
17
80
  try {
18
- const data = loadScene(scenePath);
19
- const { indexMap } = buildMaps(data);
20
-
21
- const idx = findNodeIndex(data, indexMap, nodeRef);
81
+ let root;
82
+ const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
22
83
 
23
- if (idx === null || idx < 0 || idx >= data.length) {
24
- console.log(JSON.stringify({ error: `无效的节点索引: ${nodeRef}` }));
84
+ if (ext === '.fire') {
85
+ const asset = CCSceneAsset.fromJSON(json);
86
+ root = asset._scene;
87
+ } else if (ext === '.prefab') {
88
+ const asset = CCPrefab.fromJSON(json);
89
+ root = asset._root;
90
+ } else {
91
+ console.log(JSON.stringify({ error: '不支持的文件类型,仅支持 .fire 和 .prefab' }));
25
92
  return;
26
93
  }
27
94
 
28
- const node = data[idx];
95
+ const node = findNode(root, nodePath);
96
+
29
97
  if (!node) {
30
- console.log(JSON.stringify({ error: `节点不存在: ${nodeRef}` }));
98
+ console.log(JSON.stringify({ error: `节点不存在: ${nodePath}` }));
31
99
  return;
32
100
  }
33
-
34
- console.log(JSON.stringify(getNodeState(data, node, idx)));
35
-
101
+
102
+ // 检查是否是组件属性(格式: 组件.属性)
103
+ const parts = propPath.split('.');
104
+
105
+ if (parts.length === 2) {
106
+ // 组件属性
107
+ const comp = findComponent(node, parts[0]);
108
+ if (!comp) {
109
+ console.log(JSON.stringify({ error: `组件不存在: ${parts[0]}` }));
110
+ return;
111
+ }
112
+
113
+ const value = comp[parts[1]];
114
+ if (value === undefined) {
115
+ console.log(JSON.stringify({ error: `属性不存在: ${parts[1]}` }));
116
+ return;
117
+ }
118
+
119
+ console.log(JSON.stringify({ value }));
120
+ } else {
121
+ // 节点属性
122
+ const value = getNodeProp(node, propPath);
123
+ if (value === undefined) {
124
+ console.log(JSON.stringify({ error: `属性不存在: ${propPath}` }));
125
+ return;
126
+ }
127
+
128
+ console.log(JSON.stringify({ value }));
129
+ }
130
+
36
131
  } catch (err) {
37
132
  console.log(JSON.stringify({ error: err.message }));
38
133
  }
@@ -4,108 +4,21 @@
4
4
 
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
- const { outputError, outputSuccess } = require('../lib/utils');
8
- const { createNodeData } = require('../lib/node-utils');
9
- const { parseComponent, createComponent, applyComponentProps } = require('../lib/components');
10
- const { createPrefab, generateFileId } = require('../lib/templates');
7
+ const { outputError } = require('../lib/utils');
8
+ const { buildTree } = require('../lib/node-utils');
9
+ const { createPrefab } = require('../lib/templates');
10
+ const { CCPrefab, CCPrefabInfo } = require('../lib/cc');
11
+ const { loadScriptMap, createPrefabMeta, saveMetaFile } = require('../lib/fire-utils');
12
+ const { fromJSON } = require('../lib/json-parser');
11
13
 
12
14
  /**
13
- * JSON 定义创建预制体数据
15
+ * 为节点树添加 PrefabInfo
14
16
  */
15
- function createPrefabData(nodeDef) {
16
- const data = createPrefab(nodeDef.name || 'Node');
17
+ function addPrefabInfo(node, isRoot = false) {
18
+ node._prefab = new CCPrefabInfo();
17
19
 
18
- // 更新根节点
19
- const root = data[1];
20
- applyNodeDefToNode(root, nodeDef, null);
21
-
22
- // 递归添加子节点
23
- if (nodeDef.children && nodeDef.children.length > 0) {
24
- for (const childDef of nodeDef.children) {
25
- addChildNode(data, childDef, 1);
26
- }
27
- }
28
-
29
- return data;
30
- }
31
-
32
- /**
33
- * 应用 JSON 定义到节点
34
- */
35
- function applyNodeDefToNode(node, def, parentId) {
36
- if (def.name) node._name = def.name;
37
- if (def.active !== undefined) node._active = def.active;
38
- if (def.opacity !== undefined) node._opacity = def.opacity;
39
- if (def.width !== undefined) node._contentSize.width = def.width;
40
- if (def.height !== undefined) node._contentSize.height = def.height;
41
- if (def.x !== undefined) node._trs.array[0] = def.x;
42
- if (def.y !== undefined) node._trs.array[1] = def.y;
43
- if (def.rotation !== undefined) {
44
- node._trs.array[5] = def.rotation * Math.PI / 180;
45
- node._eulerAngles.z = def.rotation;
46
- }
47
- if (def.scaleX !== undefined) node._trs.array[7] = def.scaleX;
48
- if (def.scaleY !== undefined) node._trs.array[8] = def.scaleY;
49
- if (def.anchorX !== undefined) node._anchorPoint.x = def.anchorX;
50
- if (def.anchorY !== undefined) node._anchorPoint.y = def.anchorY;
51
- if (def.color) {
52
- const { parseColor } = require('../lib/utils');
53
- const parsed = parseColor(def.color);
54
- if (parsed) {
55
- node._color = { "__type__": "cc.Color", ...parsed };
56
- }
57
- }
58
- if (parentId !== null) {
59
- node._parent = { "__id__": parentId };
60
- }
61
- }
62
-
63
- /**
64
- * 添加子节点
65
- */
66
- function addChildNode(data, def, parentIndex) {
67
- const nodeIndex = data.length;
68
- const node = createNodeData(def.name || 'Node', parentIndex, def);
69
-
70
- // 设置 _prefab 为 null,后面会添加 PrefabInfo
71
- node._prefab = null;
72
-
73
- data.push(node);
74
-
75
- // 添加组件
76
- if (def.components) {
77
- for (const compDef of def.components) {
78
- const parsed = parseComponent(compDef);
79
- if (parsed) {
80
- const comp = createComponent(parsed.type, nodeIndex);
81
- if (comp) {
82
- applyComponentProps(comp, parsed.props, node);
83
- data.push(comp);
84
- node._components.push({ "__id__": data.length - 1 });
85
- }
86
- }
87
- }
88
- }
89
-
90
- // 添加 PrefabInfo
91
- const prefabInfo = {
92
- "__type__": "cc.PrefabInfo",
93
- "root": { "__id__": 1 },
94
- "asset": { "__id__": 0 },
95
- "fileId": generateFileId(),
96
- "sync": false
97
- };
98
- data.push(prefabInfo);
99
- node._prefab = { "__id__": data.length - 1 };
100
-
101
- // 更新父节点
102
- data[parentIndex]._children.push({ "__id__": nodeIndex });
103
-
104
- // 递归处理子节点
105
- if (def.children && def.children.length > 0) {
106
- for (const childDef of def.children) {
107
- addChildNode(data, childDef, nodeIndex);
108
- }
20
+ if (node._children) {
21
+ node._children.forEach(child => addPrefabInfo(child, false));
109
22
  }
110
23
  }
111
24
 
@@ -128,11 +41,11 @@ function run(args) {
128
41
  outputPath = args[1];
129
42
  }
130
43
 
131
- // 没有传 JSON,创建默认预制体
132
- if (!jsonPath) {
133
- const prefabName = path.basename(outputPath, '.prefab');
134
-
135
- try {
44
+ const prefabName = path.basename(outputPath, '.prefab');
45
+
46
+ try {
47
+ // 没有传 JSON,创建默认预制体
48
+ if (!jsonPath) {
136
49
  if (fs.existsSync(outputPath)) {
137
50
  outputError(`文件已存在: ${outputPath}`);
138
51
  return;
@@ -143,59 +56,56 @@ function run(args) {
143
56
  fs.mkdirSync(dir, { recursive: true });
144
57
  }
145
58
 
146
- const data = createPrefab(prefabName);
59
+ const prefab = createPrefab(prefabName);
60
+ const data = prefab.toJSON();
147
61
  fs.writeFileSync(outputPath, JSON.stringify(data, null, 2), 'utf8');
148
62
 
149
- outputSuccess({
150
- path: outputPath,
151
- rootName: prefabName,
152
- nodes: 1,
153
- components: 0
154
- });
155
- return;
156
- } catch (err) {
157
- outputError(err.message);
63
+ // 生成并保存 meta 文件
64
+ saveMetaFile(outputPath, createPrefabMeta());
65
+
66
+ const scriptMap = loadScriptMap(outputPath);
67
+ console.log(buildTree(data, scriptMap, 1).trim());
158
68
  return;
159
69
  }
160
- }
161
70
 
162
- if (!fs.existsSync(jsonPath)) {
163
- outputError(`JSON 文件不存在: ${jsonPath}`);
164
- return;
165
- }
71
+ // JSON 文件创建
72
+ if (!fs.existsSync(jsonPath)) {
73
+ outputError(`JSON 文件不存在: ${jsonPath}`);
74
+ return;
75
+ }
166
76
 
167
- try {
168
77
  const input = fs.readFileSync(jsonPath, 'utf8');
169
- const cleanInput = input.replace(/^\uFEFF/, '').trim();
170
- const nodeDef = JSON.parse(cleanInput);
171
-
172
- const rootNode = Array.isArray(nodeDef) ? nodeDef[0] : nodeDef;
173
- const prefabData = createPrefabData(rootNode);
78
+ const rootNode = fromJSON(input);
79
+
80
+ // 确保根节点名称
81
+ if (!rootNode._name || rootNode._name === 'Node') {
82
+ rootNode._name = prefabName;
83
+ }
84
+
85
+ // 为所有节点添加 PrefabInfo
86
+ addPrefabInfo(rootNode, true);
87
+
88
+ // 创建预制体
89
+ const prefab = new CCPrefab();
90
+ prefab._root = rootNode;
174
91
 
175
92
  const outputDir = path.dirname(outputPath);
176
93
  if (!fs.existsSync(outputDir)) {
177
94
  fs.mkdirSync(outputDir, { recursive: true });
178
95
  }
179
96
 
180
- fs.writeFileSync(outputPath, JSON.stringify(prefabData, null, 2), 'utf8');
181
-
182
- let nodeCount = 0, compCount = 0;
183
- for (const item of prefabData) {
184
- if (item.__type__ === 'cc.Node') nodeCount++;
185
- else if (item.__type__?.startsWith('cc.') && !['cc.Prefab', 'cc.PrefabInfo'].includes(item.__type__)) {
186
- compCount++;
187
- }
188
- }
97
+ const data = prefab.toJSON();
98
+ fs.writeFileSync(outputPath, JSON.stringify(data, null, 2), 'utf8');
99
+
100
+ // 生成并保存 meta 文件
101
+ saveMetaFile(outputPath, createPrefabMeta());
189
102
 
190
- outputSuccess({
191
- path: outputPath,
192
- nodes: nodeCount,
193
- components: compCount
194
- });
103
+ const scriptMap = loadScriptMap(outputPath);
104
+ console.log(buildTree(data, scriptMap, 1).trim());
195
105
 
196
106
  } catch (err) {
197
107
  outputError(err.message);
198
108
  }
199
109
  }
200
110
 
201
- module.exports = { run };
111
+ module.exports = { run };