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.
- package/README.md +142 -0
- package/bin/cocos2d-cli.js +21 -12
- package/package.json +1 -1
- package/src/commands/add-component.js +77 -85
- package/src/commands/add.js +116 -212
- package/src/commands/create-scene.js +133 -109
- package/src/commands/get.js +113 -18
- package/src/commands/prefab-create.js +49 -139
- package/src/commands/remove-component.js +111 -0
- package/src/commands/remove.js +59 -122
- package/src/commands/set.js +121 -36
- package/src/commands/tree.js +3 -8
- package/src/lib/cc/CCButton.js +122 -0
- package/src/lib/cc/CCCamera.js +93 -0
- package/src/lib/cc/CCCanvas.js +64 -0
- package/src/lib/cc/CCColor.js +32 -0
- package/src/lib/cc/CCComponent.js +60 -0
- package/src/lib/cc/CCLabel.js +109 -0
- package/src/lib/cc/CCNode.js +242 -0
- package/src/lib/cc/CCObject.js +23 -0
- package/src/lib/cc/CCPrefab.js +242 -0
- package/src/lib/cc/CCRect.js +32 -0
- package/src/lib/cc/CCScene.js +42 -0
- package/src/lib/cc/CCSceneAsset.js +271 -0
- package/src/lib/cc/CCSize.js +26 -0
- package/src/lib/cc/CCSprite.js +82 -0
- package/src/lib/cc/CCTrs.js +74 -0
- package/src/lib/cc/CCVec2.js +26 -0
- package/src/lib/cc/CCVec3.js +29 -0
- package/src/lib/cc/CCWidget.js +98 -0
- package/src/lib/cc/index.js +40 -0
- package/src/lib/fire-utils.js +75 -1
- package/src/lib/json-parser.js +166 -0
- package/src/lib/node-utils.js +64 -28
- package/src/lib/templates.js +31 -194
- package/src/lib/utils.js +63 -0
- package/data/prefab-template.json +0 -72
- package/data/scene-template.json +0 -241
- package/src/lib/components/button.js +0 -137
- package/src/lib/components/camera.js +0 -107
- package/src/lib/components/canvas.js +0 -89
- package/src/lib/components/index.js +0 -157
- package/src/lib/components/label.js +0 -120
- package/src/lib/components/layout.js +0 -110
- package/src/lib/components/particle-system.js +0 -160
- package/src/lib/components/sprite.js +0 -98
- package/src/lib/components/widget.js +0 -122
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cocos Creator 变换数据类 (TRS = Translation, Rotation, Scale)
|
|
3
|
+
* array: [posX, posY, posZ, rotX, rotY, rotZ, rotW, scaleX, scaleY, scaleZ]
|
|
4
|
+
*/
|
|
5
|
+
class CCTrs {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.__type__ = 'TypedArray';
|
|
8
|
+
this.ctor = 'Float64Array';
|
|
9
|
+
this.array = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Position
|
|
13
|
+
get x() { return this.array[0]; }
|
|
14
|
+
set x(v) { this.array[0] = v; }
|
|
15
|
+
|
|
16
|
+
get y() { return this.array[1]; }
|
|
17
|
+
set y(v) { this.array[1] = v; }
|
|
18
|
+
|
|
19
|
+
get z() { return this.array[2]; }
|
|
20
|
+
set z(v) { this.array[2] = v; }
|
|
21
|
+
|
|
22
|
+
// Scale
|
|
23
|
+
get scaleX() { return this.array[7]; }
|
|
24
|
+
set scaleX(v) { this.array[7] = v; }
|
|
25
|
+
|
|
26
|
+
get scaleY() { return this.array[8]; }
|
|
27
|
+
set scaleY(v) { this.array[8] = v; }
|
|
28
|
+
|
|
29
|
+
get scaleZ() { return this.array[9]; }
|
|
30
|
+
set scaleZ(v) { this.array[9] = v; }
|
|
31
|
+
|
|
32
|
+
// Rotation (四元数)
|
|
33
|
+
get rotX() { return this.array[3]; }
|
|
34
|
+
set rotX(v) { this.array[3] = v; }
|
|
35
|
+
|
|
36
|
+
get rotY() { return this.array[4]; }
|
|
37
|
+
set rotY(v) { this.array[4] = v; }
|
|
38
|
+
|
|
39
|
+
get rotZ() { return this.array[5]; }
|
|
40
|
+
set rotZ(v) { this.array[5] = v; }
|
|
41
|
+
|
|
42
|
+
get rotW() { return this.array[6]; }
|
|
43
|
+
set rotW(v) { this.array[6] = v; }
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 设置位置
|
|
47
|
+
*/
|
|
48
|
+
setPosition(x, y, z = 0) {
|
|
49
|
+
this.array[0] = x;
|
|
50
|
+
this.array[1] = y;
|
|
51
|
+
this.array[2] = z;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 设置缩放
|
|
57
|
+
*/
|
|
58
|
+
setScale(x, y = x, z = 1) {
|
|
59
|
+
this.array[7] = x;
|
|
60
|
+
this.array[8] = y;
|
|
61
|
+
this.array[9] = z;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
toJSON() {
|
|
66
|
+
return {
|
|
67
|
+
__type__: this.__type__,
|
|
68
|
+
ctor: this.ctor,
|
|
69
|
+
array: [...this.array]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = CCTrs;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cocos Creator 二维向量类
|
|
3
|
+
*/
|
|
4
|
+
class CCVec2 {
|
|
5
|
+
constructor(x = 0, y = 0) {
|
|
6
|
+
this.__type__ = 'cc.Vec2';
|
|
7
|
+
this.x = x;
|
|
8
|
+
this.y = y;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
set(x, y) {
|
|
12
|
+
this.x = x;
|
|
13
|
+
this.y = y;
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
toJSON() {
|
|
18
|
+
return {
|
|
19
|
+
__type__: this.__type__,
|
|
20
|
+
x: this.x,
|
|
21
|
+
y: this.y
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = CCVec2;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cocos Creator 三维向量类
|
|
3
|
+
*/
|
|
4
|
+
class CCVec3 {
|
|
5
|
+
constructor(x = 0, y = 0, z = 0) {
|
|
6
|
+
this.__type__ = 'cc.Vec3';
|
|
7
|
+
this.x = x;
|
|
8
|
+
this.y = y;
|
|
9
|
+
this.z = z;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
set(x, y, z = 0) {
|
|
13
|
+
this.x = x;
|
|
14
|
+
this.y = y;
|
|
15
|
+
this.z = z;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
toJSON() {
|
|
20
|
+
return {
|
|
21
|
+
__type__: this.__type__,
|
|
22
|
+
x: this.x,
|
|
23
|
+
y: this.y,
|
|
24
|
+
z: this.z
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = CCVec3;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const CCComponent = require('./CCComponent');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cocos Creator Widget 组件
|
|
5
|
+
*/
|
|
6
|
+
class CCWidget extends CCComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.__type__ = 'cc.Widget';
|
|
10
|
+
|
|
11
|
+
this.alignMode = 1;
|
|
12
|
+
this._target = null;
|
|
13
|
+
this._alignFlags = 45;
|
|
14
|
+
this._left = 0;
|
|
15
|
+
this._right = 0;
|
|
16
|
+
this._top = 0;
|
|
17
|
+
this._bottom = 0;
|
|
18
|
+
this._verticalCenter = 0;
|
|
19
|
+
this._horizontalCenter = 0;
|
|
20
|
+
this._isAbsLeft = true;
|
|
21
|
+
this._isAbsRight = true;
|
|
22
|
+
this._isAbsTop = true;
|
|
23
|
+
this._isAbsBottom = true;
|
|
24
|
+
this._isAbsHorizontalCenter = true;
|
|
25
|
+
this._isAbsVerticalCenter = true;
|
|
26
|
+
this._originalWidth = 0;
|
|
27
|
+
this._originalHeight = 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 设置对齐标志
|
|
32
|
+
* 45 = 左 + 右 + 上 + 下 (全对齐)
|
|
33
|
+
*/
|
|
34
|
+
setAlignFlags(flags) {
|
|
35
|
+
this._alignFlags = flags;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 设置边距
|
|
41
|
+
*/
|
|
42
|
+
setMargins(left, right, top, bottom) {
|
|
43
|
+
this._left = left;
|
|
44
|
+
this._right = right;
|
|
45
|
+
this._top = top;
|
|
46
|
+
this._bottom = bottom;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 转换为属性面板显示格式
|
|
52
|
+
*/
|
|
53
|
+
toPanelJSON() {
|
|
54
|
+
return {
|
|
55
|
+
...super.toPanelJSON(),
|
|
56
|
+
top: this._top,
|
|
57
|
+
bottom: this._bottom,
|
|
58
|
+
left: this._left,
|
|
59
|
+
right: this._right,
|
|
60
|
+
horizontalCenter: this._horizontalCenter,
|
|
61
|
+
verticalCenter: this._verticalCenter,
|
|
62
|
+
isAbsLeft: this._isAbsLeft,
|
|
63
|
+
isAbsRight: this._isAbsRight,
|
|
64
|
+
isAbsTop: this._isAbsTop,
|
|
65
|
+
isAbsBottom: this._isAbsBottom
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
toJSON() {
|
|
70
|
+
return {
|
|
71
|
+
__type__: this.__type__,
|
|
72
|
+
_name: this._name,
|
|
73
|
+
_objFlags: this._objFlags,
|
|
74
|
+
node: this.node,
|
|
75
|
+
_enabled: this._enabled,
|
|
76
|
+
alignMode: this.alignMode,
|
|
77
|
+
_target: this._target,
|
|
78
|
+
_alignFlags: this._alignFlags,
|
|
79
|
+
_left: this._left,
|
|
80
|
+
_right: this._right,
|
|
81
|
+
_top: this._top,
|
|
82
|
+
_bottom: this._bottom,
|
|
83
|
+
_verticalCenter: this._verticalCenter,
|
|
84
|
+
_horizontalCenter: this._horizontalCenter,
|
|
85
|
+
_isAbsLeft: this._isAbsLeft,
|
|
86
|
+
_isAbsRight: this._isAbsRight,
|
|
87
|
+
_isAbsTop: this._isAbsTop,
|
|
88
|
+
_isAbsBottom: this._isAbsBottom,
|
|
89
|
+
_isAbsHorizontalCenter: this._isAbsHorizontalCenter,
|
|
90
|
+
_isAbsVerticalCenter: this._isAbsVerticalCenter,
|
|
91
|
+
_originalWidth: this._originalWidth,
|
|
92
|
+
_originalHeight: this._originalHeight,
|
|
93
|
+
_id: this._id
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = CCWidget;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const CCObject = require('./CCObject');
|
|
2
|
+
const CCNode = require('./CCNode');
|
|
3
|
+
const CCScene = require('./CCScene');
|
|
4
|
+
const CCSceneAsset = require('./CCSceneAsset');
|
|
5
|
+
const { CCPrefab, CCPrefabInfo } = require('./CCPrefab');
|
|
6
|
+
const CCColor = require('./CCColor');
|
|
7
|
+
const CCSize = require('./CCSize');
|
|
8
|
+
const CCVec2 = require('./CCVec2');
|
|
9
|
+
const CCVec3 = require('./CCVec3');
|
|
10
|
+
const CCTrs = require('./CCTrs');
|
|
11
|
+
const CCRect = require('./CCRect');
|
|
12
|
+
const CCComponent = require('./CCComponent');
|
|
13
|
+
const CCCanvas = require('./CCCanvas');
|
|
14
|
+
const CCWidget = require('./CCWidget');
|
|
15
|
+
const CCCamera = require('./CCCamera');
|
|
16
|
+
const CCSprite = require('./CCSprite');
|
|
17
|
+
const CCLabel = require('./CCLabel');
|
|
18
|
+
const CCButton = require('./CCButton');
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
CCObject,
|
|
22
|
+
CCNode,
|
|
23
|
+
CCScene,
|
|
24
|
+
CCSceneAsset,
|
|
25
|
+
CCPrefab,
|
|
26
|
+
CCPrefabInfo,
|
|
27
|
+
CCColor,
|
|
28
|
+
CCSize,
|
|
29
|
+
CCVec2,
|
|
30
|
+
CCVec3,
|
|
31
|
+
CCTrs,
|
|
32
|
+
CCRect,
|
|
33
|
+
CCComponent,
|
|
34
|
+
CCCanvas,
|
|
35
|
+
CCWidget,
|
|
36
|
+
CCCamera,
|
|
37
|
+
CCSprite,
|
|
38
|
+
CCLabel,
|
|
39
|
+
CCButton
|
|
40
|
+
};
|
package/src/lib/fire-utils.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
+
const crypto = require('crypto');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* 检测是否为预制体文件
|
|
@@ -232,7 +233,7 @@ function installPlugin(scenePath) {
|
|
|
232
233
|
fs.mkdirSync(packagesPath, { recursive: true });
|
|
233
234
|
}
|
|
234
235
|
|
|
235
|
-
const cliPluginPath = path.join(__dirname, '..', '..', 'editor-plugin'
|
|
236
|
+
const cliPluginPath = path.join(__dirname, '..', '..', 'editor-plugin');
|
|
236
237
|
|
|
237
238
|
if (!fs.existsSync(cliPluginPath)) return false;
|
|
238
239
|
|
|
@@ -277,6 +278,72 @@ function getPrefabRootIndex(data) {
|
|
|
277
278
|
return 1;
|
|
278
279
|
}
|
|
279
280
|
|
|
281
|
+
/**
|
|
282
|
+
* 生成 UUID
|
|
283
|
+
*/
|
|
284
|
+
function generateUUID() {
|
|
285
|
+
return crypto.randomUUID();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* 生成预制体的 meta 对象
|
|
290
|
+
* @param {string} uuid - 可选的 UUID,不传则自动生成
|
|
291
|
+
* @returns {object}
|
|
292
|
+
*/
|
|
293
|
+
function createPrefabMeta(uuid) {
|
|
294
|
+
return {
|
|
295
|
+
ver: '1.3.2',
|
|
296
|
+
uuid: uuid || generateUUID(),
|
|
297
|
+
importer: 'prefab',
|
|
298
|
+
optimizationPolicy: 'AUTO',
|
|
299
|
+
asyncLoadAssets: false,
|
|
300
|
+
readonly: false,
|
|
301
|
+
subMetas: {}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* 生成场景的 meta 对象
|
|
307
|
+
* @param {string} uuid - 可选的 UUID,不传则自动生成
|
|
308
|
+
* @returns {object}
|
|
309
|
+
*/
|
|
310
|
+
function createSceneMeta(uuid) {
|
|
311
|
+
return {
|
|
312
|
+
ver: '1.3.2',
|
|
313
|
+
uuid: uuid || generateUUID(),
|
|
314
|
+
importer: 'scene',
|
|
315
|
+
asyncLoadAssets: false,
|
|
316
|
+
autoReleaseAssets: false,
|
|
317
|
+
subMetas: {}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* 保存 meta 文件
|
|
323
|
+
* @param {string} filePath - 资源文件路径(.prefab 或 .fire)
|
|
324
|
+
* @param {object} meta - meta 对象
|
|
325
|
+
*/
|
|
326
|
+
function saveMetaFile(filePath, meta) {
|
|
327
|
+
const metaPath = filePath + '.meta';
|
|
328
|
+
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8');
|
|
329
|
+
return metaPath;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* 加载 meta 文件
|
|
334
|
+
* @param {string} filePath - 资源文件路径
|
|
335
|
+
* @returns {object|null}
|
|
336
|
+
*/
|
|
337
|
+
function loadMetaFile(filePath) {
|
|
338
|
+
const metaPath = filePath + '.meta';
|
|
339
|
+
try {
|
|
340
|
+
if (fs.existsSync(metaPath)) {
|
|
341
|
+
return JSON.parse(fs.readFileSync(metaPath, 'utf8'));
|
|
342
|
+
}
|
|
343
|
+
} catch (e) {}
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
|
|
280
347
|
module.exports = {
|
|
281
348
|
// 文件操作
|
|
282
349
|
loadScene,
|
|
@@ -293,6 +360,13 @@ module.exports = {
|
|
|
293
360
|
installPlugin,
|
|
294
361
|
checkPluginStatus,
|
|
295
362
|
|
|
363
|
+
// Meta 文件管理
|
|
364
|
+
generateUUID,
|
|
365
|
+
createPrefabMeta,
|
|
366
|
+
createSceneMeta,
|
|
367
|
+
saveMetaFile,
|
|
368
|
+
loadMetaFile,
|
|
369
|
+
|
|
296
370
|
// 工具函数
|
|
297
371
|
loadScriptMap,
|
|
298
372
|
generateFileId,
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON 解析器
|
|
3
|
+
* 将简化JSON转换为CCNode对象树
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { CCNode, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton, CCCamera } = require('./cc');
|
|
7
|
+
const { parseColor } = require('./utils');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 创建组件实例
|
|
11
|
+
*/
|
|
12
|
+
function createComponent(type) {
|
|
13
|
+
switch (type.toLowerCase()) {
|
|
14
|
+
case 'canvas': return new CCCanvas();
|
|
15
|
+
case 'widget': return new CCWidget();
|
|
16
|
+
case 'sprite': return new CCSprite();
|
|
17
|
+
case 'label': return new CCLabel();
|
|
18
|
+
case 'button': return new CCButton();
|
|
19
|
+
case 'camera': return new CCCamera();
|
|
20
|
+
default: return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 解析组件定义
|
|
26
|
+
*/
|
|
27
|
+
function parseComponent(compDef) {
|
|
28
|
+
if (typeof compDef === 'string') {
|
|
29
|
+
return { type: compDef, props: {} };
|
|
30
|
+
}
|
|
31
|
+
if (typeof compDef === 'object' && compDef.type) {
|
|
32
|
+
const props = { ...compDef };
|
|
33
|
+
delete props.type;
|
|
34
|
+
return { type: compDef.type, props };
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 应用组件属性
|
|
41
|
+
*/
|
|
42
|
+
function applyComponentProps(comp, props, node) {
|
|
43
|
+
if (!props) return;
|
|
44
|
+
|
|
45
|
+
for (const [key, value] of Object.entries(props)) {
|
|
46
|
+
switch (key) {
|
|
47
|
+
case 'string':
|
|
48
|
+
if (comp._string !== undefined) {
|
|
49
|
+
comp._string = value;
|
|
50
|
+
if (comp._N$string !== undefined) comp._N$string = value;
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case 'fontSize':
|
|
54
|
+
if (comp._fontSize !== undefined) comp._fontSize = value;
|
|
55
|
+
break;
|
|
56
|
+
case 'lineHeight':
|
|
57
|
+
if (comp._lineHeight !== undefined) comp._lineHeight = value;
|
|
58
|
+
break;
|
|
59
|
+
case 'sizeMode':
|
|
60
|
+
if (comp._sizeMode !== undefined) comp._sizeMode = value;
|
|
61
|
+
break;
|
|
62
|
+
case 'color':
|
|
63
|
+
if (node) {
|
|
64
|
+
const parsed = parseColor(value);
|
|
65
|
+
if (parsed && node._color) {
|
|
66
|
+
node._color.r = parsed.r;
|
|
67
|
+
node._color.g = parsed.g;
|
|
68
|
+
node._color.b = parsed.b;
|
|
69
|
+
node._color.a = parsed.a;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
if (comp[key] !== undefined) {
|
|
75
|
+
comp[key] = value;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 应用属性到节点
|
|
83
|
+
*/
|
|
84
|
+
function applyNodeProps(node, def) {
|
|
85
|
+
if (def.name) node._name = def.name;
|
|
86
|
+
if (def.active !== undefined) node._active = def.active;
|
|
87
|
+
if (def.opacity !== undefined) node._opacity = def.opacity;
|
|
88
|
+
if (def.width !== undefined) node._contentSize.width = def.width;
|
|
89
|
+
if (def.height !== undefined) node._contentSize.height = def.height;
|
|
90
|
+
if (def.x !== undefined) node._trs.array[0] = def.x;
|
|
91
|
+
if (def.y !== undefined) node._trs.array[1] = def.y;
|
|
92
|
+
if (def.rotation !== undefined) {
|
|
93
|
+
node._trs.array[5] = def.rotation * Math.PI / 180;
|
|
94
|
+
node._eulerAngles.z = def.rotation;
|
|
95
|
+
}
|
|
96
|
+
if (def.scaleX !== undefined) node._trs.array[7] = def.scaleX;
|
|
97
|
+
if (def.scaleY !== undefined) node._trs.array[8] = def.scaleY;
|
|
98
|
+
if (def.anchorX !== undefined) node._anchorPoint.x = def.anchorX;
|
|
99
|
+
if (def.anchorY !== undefined) node._anchorPoint.y = def.anchorY;
|
|
100
|
+
if (def.color) {
|
|
101
|
+
const parsed = parseColor(def.color);
|
|
102
|
+
if (parsed) {
|
|
103
|
+
node._color.set(parsed.r, parsed.g, parsed.b, parsed.a);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 解析节点定义(递归)
|
|
110
|
+
* @param {Object} def - 节点定义
|
|
111
|
+
* @returns {CCNode}
|
|
112
|
+
*/
|
|
113
|
+
function parseNode(def) {
|
|
114
|
+
const node = new CCNode(def.name || 'Node');
|
|
115
|
+
|
|
116
|
+
// 应用属性
|
|
117
|
+
applyNodeProps(node, def);
|
|
118
|
+
|
|
119
|
+
// 添加组件
|
|
120
|
+
if (def.components && def.components.length > 0) {
|
|
121
|
+
node._components = [];
|
|
122
|
+
for (const compDef of def.components) {
|
|
123
|
+
const parsed = parseComponent(compDef);
|
|
124
|
+
if (parsed) {
|
|
125
|
+
const comp = createComponent(parsed.type);
|
|
126
|
+
if (comp) {
|
|
127
|
+
applyComponentProps(comp, parsed.props, node);
|
|
128
|
+
comp.node = node;
|
|
129
|
+
node._components.push(comp);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 递归处理子节点
|
|
136
|
+
if (def.children && def.children.length > 0) {
|
|
137
|
+
node._children = [];
|
|
138
|
+
for (const childDef of def.children) {
|
|
139
|
+
const child = parseNode(childDef);
|
|
140
|
+
child._parent = node;
|
|
141
|
+
node._children.push(child);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return node;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 从简化JSON解析为CCNode树
|
|
150
|
+
* @param {Object|string} json - JSON对象或字符串
|
|
151
|
+
* @returns {CCNode}
|
|
152
|
+
*/
|
|
153
|
+
function fromJSON(json) {
|
|
154
|
+
if (typeof json === 'string') {
|
|
155
|
+
json = JSON.parse(json.replace(/^\uFEFF/, '').trim());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const rootDef = Array.isArray(json) ? json[0] : json;
|
|
159
|
+
return parseNode(rootDef);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
fromJSON,
|
|
164
|
+
parseNode,
|
|
165
|
+
applyNodeProps
|
|
166
|
+
};
|
package/src/lib/node-utils.js
CHANGED
|
@@ -147,9 +147,20 @@ function setNodeProperties(node, options) {
|
|
|
147
147
|
* @returns {object} 节点状态
|
|
148
148
|
*/
|
|
149
149
|
function getNodeState(data, node, nodeIndex) {
|
|
150
|
-
const { extractComponentProps } = require('./components');
|
|
151
150
|
const trs = node._trs?.array || [0, 0, 0, 0, 0, 0, 1, 1, 1, 1];
|
|
152
|
-
|
|
151
|
+
|
|
152
|
+
// 组件使用 toPanelJSON
|
|
153
|
+
const components = {};
|
|
154
|
+
if (node._components && node._components.length > 0) {
|
|
155
|
+
node._components.forEach(ref => {
|
|
156
|
+
const comp = data[ref.__id__];
|
|
157
|
+
if (comp && comp.toPanelJSON) {
|
|
158
|
+
const typeName = comp.__type__.replace('cc.', '');
|
|
159
|
+
components[typeName] = comp.toPanelJSON();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
153
164
|
const children = (node._children || []).map(ref => data[ref.__id__]?._name || '(unknown)');
|
|
154
165
|
|
|
155
166
|
const result = {
|
|
@@ -166,7 +177,7 @@ function getNodeState(data, node, nodeIndex) {
|
|
|
166
177
|
};
|
|
167
178
|
|
|
168
179
|
if (children.length > 0) result.children = children;
|
|
169
|
-
if (components.length > 0) result.components = components;
|
|
180
|
+
if (Object.keys(components).length > 0) result.components = components;
|
|
170
181
|
|
|
171
182
|
return result;
|
|
172
183
|
}
|
|
@@ -261,6 +272,31 @@ function deleteNode(data, nodeIndex, rebuildReferences) {
|
|
|
261
272
|
};
|
|
262
273
|
}
|
|
263
274
|
|
|
275
|
+
/**
|
|
276
|
+
* 构建组件信息字符串
|
|
277
|
+
*/
|
|
278
|
+
function buildComponentInfo(data, node, scriptMap, uuidRegex) {
|
|
279
|
+
if (!node._components || node._components.length === 0) return '';
|
|
280
|
+
|
|
281
|
+
const comps = node._components.map(c => {
|
|
282
|
+
const comp = data[c.__id__];
|
|
283
|
+
if (!comp) return '?';
|
|
284
|
+
const typeName = comp.__type__;
|
|
285
|
+
let displayName;
|
|
286
|
+
if (uuidRegex.test(typeName)) {
|
|
287
|
+
const scriptInfo = scriptMap[typeName];
|
|
288
|
+
displayName = (scriptInfo && scriptInfo.name) ? scriptInfo.name : '[MissingScript]';
|
|
289
|
+
} else if (typeName === 'MissingScript') {
|
|
290
|
+
displayName = '[MissingScript]';
|
|
291
|
+
} else {
|
|
292
|
+
displayName = typeName.replace('cc.', '');
|
|
293
|
+
}
|
|
294
|
+
return displayName;
|
|
295
|
+
}).join(', ');
|
|
296
|
+
|
|
297
|
+
return ` (${comps})`;
|
|
298
|
+
}
|
|
299
|
+
|
|
264
300
|
/**
|
|
265
301
|
* 构建节点树输出
|
|
266
302
|
* @param {Array} data - 场景数据
|
|
@@ -276,46 +312,46 @@ function buildTree(data, scriptMap, nodeIndex, prefix = '', isLast = true, isRoo
|
|
|
276
312
|
if (!node) return '';
|
|
277
313
|
|
|
278
314
|
const isSceneRoot = node.__type__ === 'cc.Scene';
|
|
279
|
-
const
|
|
315
|
+
const isPrefabRoot = node.__type__ === 'cc.Prefab';
|
|
316
|
+
const nodeName = node._name || '(unnamed)';
|
|
280
317
|
const active = node._active !== false ? '●' : '○';
|
|
281
318
|
const uuidRegex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
|
|
282
319
|
|
|
283
320
|
let result = '';
|
|
284
321
|
|
|
285
322
|
if (isSceneRoot) {
|
|
286
|
-
result =
|
|
287
|
-
} else {
|
|
288
|
-
|
|
323
|
+
result = '[Scene]\n';
|
|
324
|
+
} else if (isPrefabRoot) {
|
|
325
|
+
// 预制体直接显示根节点
|
|
326
|
+
const prefabNode = data[1];
|
|
327
|
+
if (!prefabNode) return '';
|
|
289
328
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if (!comp) return `? #${c.__id__}`;
|
|
295
|
-
const typeName = comp.__type__;
|
|
296
|
-
let displayName;
|
|
297
|
-
if (uuidRegex.test(typeName)) {
|
|
298
|
-
const scriptInfo = scriptMap[typeName];
|
|
299
|
-
displayName = (scriptInfo && scriptInfo.name) ? scriptInfo.name : '[MissingScript]';
|
|
300
|
-
} else if (typeName === 'MissingScript') {
|
|
301
|
-
displayName = '[MissingScript]';
|
|
302
|
-
} else {
|
|
303
|
-
displayName = typeName.replace('cc.', '');
|
|
304
|
-
}
|
|
305
|
-
return `${displayName} #${c.__id__}`;
|
|
306
|
-
}).join(', ');
|
|
307
|
-
result += ` (${comps})`;
|
|
308
|
-
}
|
|
329
|
+
const prefabActive = prefabNode._active !== false ? '●' : '○';
|
|
330
|
+
result = prefabActive + ' ' + (prefabNode._name || 'Root');
|
|
331
|
+
result += buildComponentInfo(data, prefabNode, scriptMap, uuidRegex);
|
|
332
|
+
result += '\n';
|
|
309
333
|
|
|
334
|
+
// 处理子节点
|
|
335
|
+
if (prefabNode._children && prefabNode._children.length > 0) {
|
|
336
|
+
prefabNode._children.forEach((childRef, idx) => {
|
|
337
|
+
const childIsLast = idx === prefabNode._children.length - 1;
|
|
338
|
+
result += buildTree(data, scriptMap, childRef.__id__, '', childIsLast, false);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
return result;
|
|
342
|
+
} else {
|
|
343
|
+
const connector = isRoot ? '' : (isLast ? '└── ' : '├── ');
|
|
344
|
+
result = prefix + connector + (isRoot ? '' : active + ' ') + nodeName;
|
|
345
|
+
result += buildComponentInfo(data, node, scriptMap, uuidRegex);
|
|
310
346
|
result += '\n';
|
|
311
347
|
}
|
|
312
348
|
|
|
313
349
|
// 处理子节点
|
|
314
350
|
if (node._children && node._children.length > 0) {
|
|
351
|
+
const childPrefix = prefix + (isSceneRoot ? '' : (isRoot ? '' : (isLast ? ' ' : '│ ')));
|
|
315
352
|
node._children.forEach((childRef, idx) => {
|
|
316
353
|
const childIsLast = idx === node._children.length - 1;
|
|
317
|
-
|
|
318
|
-
result += buildTree(data, scriptMap, childRef.__id__, childPrefix, childIsLast, isSceneRoot);
|
|
354
|
+
result += buildTree(data, scriptMap, childRef.__id__, childPrefix, childIsLast, false);
|
|
319
355
|
});
|
|
320
356
|
}
|
|
321
357
|
|