cocos2d-cli 1.1.2 → 1.4.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.
- package/bin/{cocos-cli.js → cocos2d-cli.js} +29 -12
- package/package.json +3 -3
- package/src/commands/add-component.js +23 -54
- package/src/commands/add.js +31 -114
- package/src/commands/build.js +1 -1
- package/src/commands/create-scene.js +93 -455
- package/src/commands/get.js +5 -154
- package/src/commands/prefab-create.js +108 -368
- package/src/commands/remove.js +123 -59
- package/src/commands/set.js +12 -245
- package/src/commands/tree.js +4 -3
- package/src/lib/components/button.js +137 -0
- package/src/lib/components/camera.js +107 -0
- package/src/lib/components/canvas.js +89 -0
- package/src/lib/components/index.js +157 -0
- package/src/lib/components/label.js +120 -0
- package/src/lib/components/layout.js +110 -0
- package/src/lib/components/particle-system.js +160 -0
- package/src/lib/components/sprite.js +98 -0
- package/src/lib/components/widget.js +122 -0
- package/src/lib/fire-utils.js +58 -392
- package/src/lib/node-utils.js +359 -0
- package/src/lib/templates.js +212 -0
- package/src/lib/utils.js +139 -0
- package/src/commands/delete.js +0 -74
- package/src/commands/remove-component.js +0 -63
- package/src/lib/components.js +0 -404
|
@@ -1,506 +1,145 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* create-scene 命令 - 从 JSON 结构创建场景文件
|
|
3
|
-
*
|
|
4
|
-
* JSON 格式示例:
|
|
5
|
-
* {
|
|
6
|
-
* "name": "Panel",
|
|
7
|
-
* "width": 400,
|
|
8
|
-
* "height": 300,
|
|
9
|
-
* "color": "#ffffff",
|
|
10
|
-
* "components": [
|
|
11
|
-
* { "type": "sprite", "sizeMode": 1 },
|
|
12
|
-
* { "type": "widget", "top": 0, "bottom": 0 }
|
|
13
|
-
* ],
|
|
14
|
-
* "children": [...]
|
|
15
|
-
* }
|
|
16
|
-
*
|
|
17
|
-
* 节点属性:name, width, height, x, y, color, opacity, anchorX, anchorY, rotation, scaleX, scaleY, active
|
|
18
|
-
* 组件属性:type + 各组件特有属性
|
|
19
|
-
*
|
|
20
|
-
* 场景会自动包含 Canvas 和 Main Camera 节点
|
|
21
3
|
*/
|
|
22
4
|
|
|
23
5
|
const fs = require('fs');
|
|
24
6
|
const path = require('path');
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
'sprite': 'sprite',
|
|
30
|
-
'label': 'label',
|
|
31
|
-
'button': 'button',
|
|
32
|
-
'layout': 'layout',
|
|
33
|
-
'widget': 'widget',
|
|
34
|
-
'camera': 'camera',
|
|
35
|
-
'canvas': 'canvas',
|
|
36
|
-
'particle': 'particleSystem',
|
|
37
|
-
'particlesystem': 'particleSystem'
|
|
38
|
-
};
|
|
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');
|
|
39
11
|
|
|
40
12
|
/**
|
|
41
|
-
*
|
|
13
|
+
* 从 JSON 定义创建场景数据
|
|
42
14
|
*/
|
|
43
|
-
function
|
|
44
|
-
|
|
15
|
+
function createSceneData(nodeDefs, sceneName) {
|
|
16
|
+
const data = createScene(sceneName);
|
|
45
17
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
r: parseInt(hex.substring(0, 2), 16),
|
|
50
|
-
g: parseInt(hex.substring(2, 4), 16),
|
|
51
|
-
b: parseInt(hex.substring(4, 6), 16),
|
|
52
|
-
a: 255
|
|
53
|
-
};
|
|
54
|
-
} else if (hex.length === 8) {
|
|
55
|
-
return {
|
|
56
|
-
r: parseInt(hex.substring(0, 2), 16),
|
|
57
|
-
g: parseInt(hex.substring(2, 4), 16),
|
|
58
|
-
b: parseInt(hex.substring(4, 6), 16),
|
|
59
|
-
a: parseInt(hex.substring(6, 8), 16)
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 生成 UUID
|
|
67
|
-
*/
|
|
68
|
-
function generateUUID() {
|
|
69
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
70
|
-
const r = Math.random() * 16 | 0;
|
|
71
|
-
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
72
|
-
return v.toString(16);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
18
|
+
// Canvas 节点索引
|
|
19
|
+
const canvasIndex = 2;
|
|
75
20
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
*/
|
|
79
|
-
function parseComponent(compDef) {
|
|
80
|
-
if (typeof compDef === 'string') {
|
|
81
|
-
const type = COMPONENT_TYPES[compDef.toLowerCase()];
|
|
82
|
-
return type ? { type, props: {} } : null;
|
|
83
|
-
}
|
|
21
|
+
// 支持数组或单个节点
|
|
22
|
+
const nodes = Array.isArray(nodeDefs) ? nodeDefs : [nodeDefs];
|
|
84
23
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const props = { ...compDef };
|
|
90
|
-
delete props.type;
|
|
91
|
-
return { type, props };
|
|
24
|
+
// 添加用户节点到 Canvas
|
|
25
|
+
for (const nodeDef of nodes) {
|
|
26
|
+
addUserNode(data, nodeDef, canvasIndex);
|
|
92
27
|
}
|
|
93
|
-
|
|
94
|
-
return
|
|
28
|
+
|
|
29
|
+
return data;
|
|
95
30
|
}
|
|
96
31
|
|
|
97
32
|
/**
|
|
98
|
-
*
|
|
33
|
+
* 添加用户节点
|
|
99
34
|
*/
|
|
100
|
-
function
|
|
101
|
-
|
|
35
|
+
function addUserNode(data, def, parentIndex) {
|
|
36
|
+
const nodeIndex = data.length;
|
|
37
|
+
const node = createNodeData(def.name || 'Node', parentIndex, def);
|
|
102
38
|
|
|
103
|
-
|
|
39
|
+
data.push(node);
|
|
104
40
|
|
|
105
|
-
//
|
|
106
|
-
if (
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
let alignFlags = 0;
|
|
116
|
-
|
|
117
|
-
for (const dir of ['top', 'bottom', 'left', 'right', 'horizontalCenter', 'verticalCenter']) {
|
|
118
|
-
if (props[dir] !== undefined && props[dir] !== null) {
|
|
119
|
-
alignFlags |= ALIGN[dir];
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (alignFlags > 0) {
|
|
124
|
-
comp._alignFlags = alignFlags;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 通用属性映射
|
|
129
|
-
const propMap = {
|
|
130
|
-
'sizeMode': '_sizeMode',
|
|
131
|
-
'fillType': '_fillType',
|
|
132
|
-
'fillCenter': '_fillCenter',
|
|
133
|
-
'fillStart': '_fillStart',
|
|
134
|
-
'fillRange': '_fillRange',
|
|
135
|
-
'trim': '_isTrimmedMode',
|
|
136
|
-
'string': '_string',
|
|
137
|
-
'fontSize': '_fontSize',
|
|
138
|
-
'lineHeight': '_lineHeight',
|
|
139
|
-
'horizontalAlign': '_N$horizontalAlign',
|
|
140
|
-
'verticalAlign': '_N$verticalAlign',
|
|
141
|
-
'overflow': '_N$overflow',
|
|
142
|
-
'fontFamily': '_N$fontFamily',
|
|
143
|
-
'wrap': '_enableWrapText',
|
|
144
|
-
'alignFlags': '_alignFlags',
|
|
145
|
-
'left': '_left',
|
|
146
|
-
'right': '_right',
|
|
147
|
-
'top': '_top',
|
|
148
|
-
'bottom': '_bottom',
|
|
149
|
-
'horizontalCenter': '_horizontalCenter',
|
|
150
|
-
'verticalCenter': '_verticalCenter',
|
|
151
|
-
'isAbsLeft': '_isAbsLeft',
|
|
152
|
-
'isAbsRight': '_isAbsRight',
|
|
153
|
-
'isAbsTop': '_isAbsTop',
|
|
154
|
-
'isAbsBottom': '_isAbsBottom',
|
|
155
|
-
'interactable': '_N$interactable',
|
|
156
|
-
'transition': '_N$transition',
|
|
157
|
-
'zoomScale': 'zoomScale',
|
|
158
|
-
'duration': 'duration',
|
|
159
|
-
'layoutType': '_N$layoutType',
|
|
160
|
-
'cellSize': '_N$cellSize',
|
|
161
|
-
'startAxis': '_N$startAxis',
|
|
162
|
-
'paddingLeft': '_N$paddingLeft',
|
|
163
|
-
'paddingRight': '_N$paddingRight',
|
|
164
|
-
'paddingTop': '_N$paddingTop',
|
|
165
|
-
'paddingBottom': '_N$paddingBottom',
|
|
166
|
-
'spacingX': '_N$spacingX',
|
|
167
|
-
'spacingY': '_N$spacingY',
|
|
168
|
-
'resize': '_resize',
|
|
169
|
-
'designResolution': '_designResolution',
|
|
170
|
-
'fitWidth': '_fitWidth',
|
|
171
|
-
'fitHeight': '_fitHeight',
|
|
172
|
-
'orthoSize': '_orthoSize',
|
|
173
|
-
'backgroundColor': '_backgroundColor',
|
|
174
|
-
'cullingMask': '_cullingMask',
|
|
175
|
-
'zoomRatio': '_zoomRatio'
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
if (type === 'cc.Label' && props.string !== undefined) {
|
|
179
|
-
comp._N$string = props.string;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
for (const [key, value] of Object.entries(props)) {
|
|
183
|
-
const compKey = propMap[key];
|
|
184
|
-
if (compKey) {
|
|
185
|
-
if (key === 'fillCenter' && Array.isArray(value)) {
|
|
186
|
-
comp[compKey] = { "__type__": "cc.Vec2", "x": value[0], "y": value[1] };
|
|
187
|
-
} else if (key === 'cellSize' && Array.isArray(value)) {
|
|
188
|
-
comp[compKey] = { "__type__": "cc.Size", "width": value[0], "height": value[1] };
|
|
189
|
-
} else if (key === 'designResolution' && Array.isArray(value)) {
|
|
190
|
-
comp[compKey] = { "__type__": "cc.Size", "width": value[0], "height": value[1] };
|
|
191
|
-
} else if ((key === 'backgroundColor' || key === 'color') && typeof value === 'string') {
|
|
192
|
-
const color = parseColor(value);
|
|
193
|
-
if (color) {
|
|
194
|
-
comp[compKey] = { "__type__": "cc.Color", ...color };
|
|
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 });
|
|
195
51
|
}
|
|
196
|
-
} else {
|
|
197
|
-
comp[compKey] = value;
|
|
198
52
|
}
|
|
199
53
|
}
|
|
200
54
|
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* 创建场景数据结构
|
|
205
|
-
*/
|
|
206
|
-
function createSceneData(nodeDefs, sceneName) {
|
|
207
|
-
const data = [];
|
|
208
|
-
|
|
209
|
-
// 场景 UUID
|
|
210
|
-
const sceneUUID = generateUUID();
|
|
211
|
-
const canvasUUID = generateUUID();
|
|
212
|
-
const cameraUUID = generateUUID();
|
|
213
|
-
|
|
214
|
-
// 索引 0: cc.SceneAsset
|
|
215
|
-
data.push({
|
|
216
|
-
"__type__": "cc.SceneAsset",
|
|
217
|
-
"_name": sceneName || "NewScene",
|
|
218
|
-
"_objFlags": 0,
|
|
219
|
-
"_native": "",
|
|
220
|
-
"scene": { "__id__": 1 }
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// 索引 1: cc.Scene
|
|
224
|
-
data.push({
|
|
225
|
-
"__type__": "cc.Scene",
|
|
226
|
-
"_name": sceneName || "NewScene",
|
|
227
|
-
"_objFlags": 0,
|
|
228
|
-
"_parent": null,
|
|
229
|
-
"_children": [{ "__id__": 2 }],
|
|
230
|
-
"_active": true,
|
|
231
|
-
"_components": [],
|
|
232
|
-
"_prefab": null,
|
|
233
|
-
"_opacity": 255,
|
|
234
|
-
"_color": { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 },
|
|
235
|
-
"_contentSize": { "__type__": "cc.Size", "width": 0, "height": 0 },
|
|
236
|
-
"_anchorPoint": { "__type__": "cc.Vec2", "x": 0, "y": 0 },
|
|
237
|
-
"_trs": { "__type__": "TypedArray", "ctor": "Float64Array", "array": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] },
|
|
238
|
-
"_is3DNode": true,
|
|
239
|
-
"_groupIndex": 0,
|
|
240
|
-
"groupIndex": 0,
|
|
241
|
-
"autoReleaseAssets": false,
|
|
242
|
-
"_id": sceneUUID
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// 索引 2: Canvas 节点
|
|
246
|
-
data.push({
|
|
247
|
-
"__type__": "cc.Node",
|
|
248
|
-
"_name": "Canvas",
|
|
249
|
-
"_objFlags": 0,
|
|
250
|
-
"_parent": { "__id__": 1 },
|
|
251
|
-
"_children": [{ "__id__": 3 }], // Main Camera
|
|
252
|
-
"_active": true,
|
|
253
|
-
"_components": [{ "__id__": 5 }, { "__id__": 6 }], // Canvas, Widget
|
|
254
|
-
"_prefab": null,
|
|
255
|
-
"_opacity": 255,
|
|
256
|
-
"_color": { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 },
|
|
257
|
-
"_contentSize": { "__type__": "cc.Size", "width": 960, "height": 640 },
|
|
258
|
-
"_anchorPoint": { "__type__": "cc.Vec2", "x": 0.5, "y": 0.5 },
|
|
259
|
-
"_trs": { "__type__": "TypedArray", "ctor": "Float64Array", "array": [480, 320, 0, 0, 0, 0, 1, 1, 1, 1] },
|
|
260
|
-
"_eulerAngles": { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": 0 },
|
|
261
|
-
"_skewX": 0,
|
|
262
|
-
"_skewY": 0,
|
|
263
|
-
"_is3DNode": false,
|
|
264
|
-
"_groupIndex": 0,
|
|
265
|
-
"groupIndex": 0,
|
|
266
|
-
"_id": canvasUUID
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// 索引 3: Main Camera 节点
|
|
270
|
-
data.push({
|
|
271
|
-
"__type__": "cc.Node",
|
|
272
|
-
"_name": "Main Camera",
|
|
273
|
-
"_objFlags": 0,
|
|
274
|
-
"_parent": { "__id__": 2 },
|
|
275
|
-
"_children": [],
|
|
276
|
-
"_active": true,
|
|
277
|
-
"_components": [{ "__id__": 4 }], // Camera
|
|
278
|
-
"_prefab": null,
|
|
279
|
-
"_opacity": 255,
|
|
280
|
-
"_color": { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 },
|
|
281
|
-
"_contentSize": { "__type__": "cc.Size", "width": 0, "height": 0 },
|
|
282
|
-
"_anchorPoint": { "__type__": "cc.Vec2", "x": 0.5, "y": 0.5 },
|
|
283
|
-
"_trs": { "__type__": "TypedArray", "ctor": "Float64Array", "array": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] },
|
|
284
|
-
"_eulerAngles": { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": 0 },
|
|
285
|
-
"_skewX": 0,
|
|
286
|
-
"_skewY": 0,
|
|
287
|
-
"_is3DNode": false,
|
|
288
|
-
"_groupIndex": 0,
|
|
289
|
-
"groupIndex": 0,
|
|
290
|
-
"_id": cameraUUID
|
|
291
|
-
});
|
|
292
55
|
|
|
293
|
-
//
|
|
294
|
-
data.push({
|
|
295
|
-
"__type__": "cc.Camera",
|
|
296
|
-
"_name": "",
|
|
297
|
-
"_objFlags": 0,
|
|
298
|
-
"node": { "__id__": 3 },
|
|
299
|
-
"_enabled": true,
|
|
300
|
-
"_cullingMask": 4294967295,
|
|
301
|
-
"_clearFlags": 7,
|
|
302
|
-
"_backgroundColor": { "__type__": "cc.Color", "r": 0, "g": 0, "b": 0, "a": 255 },
|
|
303
|
-
"_depth": -1,
|
|
304
|
-
"_zoomRatio": 1,
|
|
305
|
-
"_targetTexture": null,
|
|
306
|
-
"_fov": 60,
|
|
307
|
-
"_orthoSize": 10,
|
|
308
|
-
"_nearClip": 1,
|
|
309
|
-
"_farClip": 4096,
|
|
310
|
-
"_ortho": true,
|
|
311
|
-
"_rect": { "__type__": "cc.Rect", "x": 0, "y": 0, "width": 1, "height": 1 },
|
|
312
|
-
"_renderStages": 1,
|
|
313
|
-
"_alignWithScreen": true,
|
|
314
|
-
"_id": generateId()
|
|
315
|
-
});
|
|
56
|
+
// 更新父节点的 _children
|
|
57
|
+
data[parentIndex]._children.push({ "__id__": nodeIndex });
|
|
316
58
|
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
"_objFlags": 0,
|
|
322
|
-
"node": { "__id__": 2 },
|
|
323
|
-
"_enabled": true,
|
|
324
|
-
"_designResolution": { "__type__": "cc.Size", "width": 960, "height": 640 },
|
|
325
|
-
"_fitWidth": false,
|
|
326
|
-
"_fitHeight": true,
|
|
327
|
-
"_id": generateId()
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
// 索引 6: Widget 组件 (Canvas)
|
|
331
|
-
data.push({
|
|
332
|
-
"__type__": "cc.Widget",
|
|
333
|
-
"_name": "",
|
|
334
|
-
"_objFlags": 0,
|
|
335
|
-
"node": { "__id__": 2 },
|
|
336
|
-
"_enabled": true,
|
|
337
|
-
"alignMode": 1,
|
|
338
|
-
"_target": null,
|
|
339
|
-
"_alignFlags": 45,
|
|
340
|
-
"_left": 0,
|
|
341
|
-
"_right": 0,
|
|
342
|
-
"_top": 0,
|
|
343
|
-
"_bottom": 0,
|
|
344
|
-
"_verticalCenter": 0,
|
|
345
|
-
"_horizontalCenter": 0,
|
|
346
|
-
"_isAbsLeft": true,
|
|
347
|
-
"_isAbsRight": true,
|
|
348
|
-
"_isAbsTop": true,
|
|
349
|
-
"_isAbsBottom": true,
|
|
350
|
-
"_isAbsHorizontalCenter": true,
|
|
351
|
-
"_isAbsVerticalCenter": true,
|
|
352
|
-
"_originalWidth": 0,
|
|
353
|
-
"_originalHeight": 0,
|
|
354
|
-
"_id": generateId()
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
// Canvas 节点索引
|
|
358
|
-
const canvasIndex = 2;
|
|
359
|
-
|
|
360
|
-
// 递归添加用户节点
|
|
361
|
-
function addNode(def, parentIndex) {
|
|
362
|
-
const nodeIndex = data.length;
|
|
363
|
-
const uuid = generateUUID();
|
|
364
|
-
|
|
365
|
-
// 解析组件
|
|
366
|
-
const compList = (def.components || [])
|
|
367
|
-
.map(parseComponent)
|
|
368
|
-
.filter(Boolean);
|
|
369
|
-
|
|
370
|
-
// 解析颜色
|
|
371
|
-
let color = { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 };
|
|
372
|
-
if (def.color) {
|
|
373
|
-
const parsed = parseColor(def.color);
|
|
374
|
-
if (parsed) {
|
|
375
|
-
color = { "__type__": "cc.Color", ...parsed };
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// 解析尺寸和位置
|
|
380
|
-
const width = def.width || 0;
|
|
381
|
-
const height = def.height || 0;
|
|
382
|
-
const anchorX = def.anchorX !== undefined ? def.anchorX : 0.5;
|
|
383
|
-
const anchorY = def.anchorY !== undefined ? def.anchorY : 0.5;
|
|
384
|
-
const rotation = def.rotation || 0;
|
|
385
|
-
const scaleX = def.scaleX !== undefined ? def.scaleX : 1;
|
|
386
|
-
const scaleY = def.scaleY !== undefined ? def.scaleY : 1;
|
|
387
|
-
|
|
388
|
-
// 创建节点
|
|
389
|
-
const node = {
|
|
390
|
-
"__type__": "cc.Node",
|
|
391
|
-
"_name": def.name || 'Node',
|
|
392
|
-
"_objFlags": 0,
|
|
393
|
-
"_parent": { "__id__": parentIndex },
|
|
394
|
-
"_children": [],
|
|
395
|
-
"_active": def.active !== false,
|
|
396
|
-
"_components": [],
|
|
397
|
-
"_prefab": null,
|
|
398
|
-
"_opacity": def.opacity !== undefined ? def.opacity : 255,
|
|
399
|
-
"_color": color,
|
|
400
|
-
"_contentSize": { "__type__": "cc.Size", width, height },
|
|
401
|
-
"_anchorPoint": { "__type__": "cc.Vec2", "x": anchorX, "y": anchorY },
|
|
402
|
-
"_trs": {
|
|
403
|
-
"__type__": "TypedArray",
|
|
404
|
-
"ctor": "Float64Array",
|
|
405
|
-
"array": [
|
|
406
|
-
def.x || 0,
|
|
407
|
-
def.y || 0,
|
|
408
|
-
0, 0, 0,
|
|
409
|
-
rotation * Math.PI / 180,
|
|
410
|
-
1, scaleX, scaleY, 1
|
|
411
|
-
]
|
|
412
|
-
},
|
|
413
|
-
"_eulerAngles": { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": rotation },
|
|
414
|
-
"_skewX": 0,
|
|
415
|
-
"_skewY": 0,
|
|
416
|
-
"_is3DNode": false,
|
|
417
|
-
"_groupIndex": 0,
|
|
418
|
-
"groupIndex": 0,
|
|
419
|
-
"_id": uuid
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
data.push(node);
|
|
423
|
-
|
|
424
|
-
// 添加组件
|
|
425
|
-
for (const { type, props } of compList) {
|
|
426
|
-
if (Components[type]) {
|
|
427
|
-
const comp = Components[type](nodeIndex);
|
|
428
|
-
applyComponentProps(comp, props);
|
|
429
|
-
const compIndex = data.length;
|
|
430
|
-
data.push(comp);
|
|
431
|
-
node._components.push({ "__id__": compIndex });
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// 更新父节点的 _children
|
|
436
|
-
data[parentIndex]._children.push({ "__id__": nodeIndex });
|
|
437
|
-
|
|
438
|
-
// 递归处理子节点
|
|
439
|
-
if (def.children && def.children.length > 0) {
|
|
440
|
-
for (const child of def.children) {
|
|
441
|
-
addNode(child, nodeIndex);
|
|
442
|
-
}
|
|
59
|
+
// 递归处理子节点
|
|
60
|
+
if (def.children && def.children.length > 0) {
|
|
61
|
+
for (const childDef of def.children) {
|
|
62
|
+
addUserNode(data, childDef, nodeIndex);
|
|
443
63
|
}
|
|
444
|
-
|
|
445
|
-
return nodeIndex;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// 支持数组或单个节点
|
|
449
|
-
const nodes = Array.isArray(nodeDefs) ? nodeDefs : [nodeDefs];
|
|
450
|
-
|
|
451
|
-
// 添加用户节点到 Canvas
|
|
452
|
-
for (const nodeDef of nodes) {
|
|
453
|
-
addNode(nodeDef, canvasIndex);
|
|
454
64
|
}
|
|
455
|
-
|
|
456
|
-
return data;
|
|
457
65
|
}
|
|
458
66
|
|
|
459
67
|
function run(args) {
|
|
460
68
|
if (args.length < 1) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
hint: '
|
|
464
|
-
|
|
465
|
-
}));
|
|
69
|
+
outputError({
|
|
70
|
+
message: '用法: cocos2d-cli create-scene [JSON文件路径] <输出路径.fire>',
|
|
71
|
+
hint: '不传 JSON 则创建默认场景'
|
|
72
|
+
});
|
|
466
73
|
return;
|
|
467
74
|
}
|
|
468
75
|
|
|
469
|
-
|
|
76
|
+
let jsonPath = null;
|
|
77
|
+
let outputPath;
|
|
78
|
+
|
|
79
|
+
if (args.length === 1) {
|
|
80
|
+
outputPath = args[0];
|
|
81
|
+
} else {
|
|
82
|
+
jsonPath = args[0];
|
|
83
|
+
outputPath = args[1];
|
|
84
|
+
}
|
|
85
|
+
|
|
470
86
|
const sceneName = path.basename(outputPath, '.fire');
|
|
471
87
|
|
|
472
|
-
//
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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');
|
|
103
|
+
|
|
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
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
outputSuccess({
|
|
113
|
+
path: outputPath,
|
|
114
|
+
nodes: nodeCount,
|
|
115
|
+
components: compCount
|
|
116
|
+
});
|
|
117
|
+
return;
|
|
118
|
+
} catch (err) {
|
|
119
|
+
outputError(err.message);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
477
122
|
}
|
|
478
123
|
|
|
479
|
-
if (!
|
|
480
|
-
|
|
481
|
-
error: '请通过 stdin 提供 JSON 结构'
|
|
482
|
-
}));
|
|
124
|
+
if (!fs.existsSync(jsonPath)) {
|
|
125
|
+
outputError(`JSON 文件不存在: ${jsonPath}`);
|
|
483
126
|
return;
|
|
484
127
|
}
|
|
485
128
|
|
|
486
129
|
try {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const nodeDef = JSON.parse(
|
|
130
|
+
const input = fs.readFileSync(jsonPath, 'utf8');
|
|
131
|
+
const cleanInput = input.replace(/^\uFEFF/, '').trim();
|
|
132
|
+
const nodeDef = JSON.parse(cleanInput);
|
|
490
133
|
|
|
491
|
-
// 生成场景数据
|
|
492
134
|
const sceneData = createSceneData(nodeDef, sceneName);
|
|
493
135
|
|
|
494
|
-
// 确保输出目录存在
|
|
495
136
|
const outputDir = path.dirname(outputPath);
|
|
496
137
|
if (!fs.existsSync(outputDir)) {
|
|
497
138
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
498
139
|
}
|
|
499
140
|
|
|
500
|
-
// 保存文件
|
|
501
141
|
fs.writeFileSync(outputPath, JSON.stringify(sceneData, null, 2), 'utf8');
|
|
502
142
|
|
|
503
|
-
// 统计信息
|
|
504
143
|
let nodeCount = 0, compCount = 0;
|
|
505
144
|
for (const item of sceneData) {
|
|
506
145
|
if (item.__type__ === 'cc.Node') nodeCount++;
|
|
@@ -509,15 +148,14 @@ function run(args) {
|
|
|
509
148
|
}
|
|
510
149
|
}
|
|
511
150
|
|
|
512
|
-
|
|
513
|
-
success: true,
|
|
151
|
+
outputSuccess({
|
|
514
152
|
path: outputPath,
|
|
515
153
|
nodes: nodeCount,
|
|
516
154
|
components: compCount
|
|
517
|
-
})
|
|
155
|
+
});
|
|
518
156
|
|
|
519
157
|
} catch (err) {
|
|
520
|
-
|
|
158
|
+
outputError(err.message);
|
|
521
159
|
}
|
|
522
160
|
}
|
|
523
161
|
|