cocos2d-cli 1.6.4 → 2.0.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/data/script_map.json +25 -25
- package/dist/bin/cocos2d-cli.js +64 -0
- package/dist/src/commands/add-component.js +3 -0
- package/dist/src/commands/add.js +3 -0
- package/dist/src/commands/build.js +6 -0
- package/dist/src/commands/create-scene.js +3 -0
- package/dist/src/commands/get.js +3 -0
- package/dist/src/commands/prefab-create.js +109 -0
- package/dist/src/commands/remove-component.js +3 -0
- package/dist/src/commands/remove.js +3 -0
- package/dist/src/commands/screenshot.js +41 -0
- package/dist/src/commands/set-component.js +3 -0
- package/dist/src/commands/set.js +3 -0
- package/dist/src/commands/tree.js +24 -0
- package/{src → dist/src}/lib/cc/CCButton.js +26 -33
- package/{src → dist/src}/lib/cc/CCCamera.js +20 -30
- package/{src → dist/src}/lib/cc/CCCanvas.js +10 -15
- package/{src → dist/src}/lib/cc/CCColor.js +6 -8
- package/{src → dist/src}/lib/cc/CCComponent.js +8 -29
- package/{src → dist/src}/lib/cc/CCLabel.js +44 -51
- package/{src → dist/src}/lib/cc/CCNode.js +52 -118
- package/{src → dist/src}/lib/cc/CCObject.js +4 -8
- package/{src → dist/src}/lib/cc/CCPrefab.js +77 -100
- package/{src → dist/src}/lib/cc/CCRect.js +6 -8
- package/{src → dist/src}/lib/cc/CCRichText.js +10 -16
- package/{src → dist/src}/lib/cc/CCScene.js +3 -13
- package/dist/src/lib/cc/CCSceneAsset.js +242 -0
- package/{src → dist/src}/lib/cc/CCSize.js +4 -8
- package/{src → dist/src}/lib/cc/CCSprite.js +21 -33
- package/{src → dist/src}/lib/cc/CCTrs.js +4 -29
- package/{src → dist/src}/lib/cc/CCVec2.js +4 -8
- package/{src → dist/src}/lib/cc/CCVec3.js +5 -8
- package/{src → dist/src}/lib/cc/CCWidget.js +20 -24
- package/dist/src/lib/fire-utils.js +86 -0
- package/dist/src/lib/json-parser.js +114 -0
- package/dist/src/lib/node-utils.js +131 -0
- package/{src → dist/src}/lib/screenshot-core.js +54 -119
- package/dist/src/lib/templates.js +17 -0
- package/dist/src/lib/utils.js +81 -0
- package/package.json +40 -33
- package/bin/cocos2d-cli.js +0 -152
- package/src/commands/add-component.js +0 -112
- package/src/commands/add.js +0 -177
- package/src/commands/build.js +0 -78
- package/src/commands/create-scene.js +0 -181
- package/src/commands/get.js +0 -108
- package/src/commands/prefab-create.js +0 -111
- package/src/commands/remove-component.js +0 -111
- package/src/commands/remove.js +0 -99
- package/src/commands/screenshot.js +0 -108
- package/src/commands/set-component.js +0 -119
- package/src/commands/set.js +0 -107
- package/src/commands/tree.js +0 -29
- package/src/lib/cc/CCSceneAsset.js +0 -303
- package/src/lib/cc/index.js +0 -42
- package/src/lib/fire-utils.js +0 -374
- package/src/lib/json-parser.js +0 -185
- package/src/lib/node-utils.js +0 -395
- package/src/lib/screenshot/favicon.ico +0 -0
- package/src/lib/screenshot/index.html +0 -30
- package/src/lib/templates.js +0 -49
- package/src/lib/utils.js +0 -202
package/src/lib/json-parser.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON 解析器
|
|
3
|
-
* 将简化JSON转换为CCNode对象树
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { CCNode, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton, CCCamera, CCRichText } = 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
|
-
case 'richtext': return new CCRichText();
|
|
21
|
-
default: return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 解析组件定义
|
|
27
|
-
*/
|
|
28
|
-
function parseComponent(compDef) {
|
|
29
|
-
if (typeof compDef === 'string') {
|
|
30
|
-
return { type: compDef, props: {} };
|
|
31
|
-
}
|
|
32
|
-
if (typeof compDef === 'object' && compDef.type) {
|
|
33
|
-
const props = { ...compDef };
|
|
34
|
-
delete props.type;
|
|
35
|
-
return { type: compDef.type, props };
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 应用组件属性
|
|
42
|
-
*/
|
|
43
|
-
function applyComponentProps(comp, props, node) {
|
|
44
|
-
if (!props) return;
|
|
45
|
-
|
|
46
|
-
for (const [key, value] of Object.entries(props)) {
|
|
47
|
-
switch (key) {
|
|
48
|
-
case 'string':
|
|
49
|
-
if (comp._string !== undefined) {
|
|
50
|
-
comp._string = value;
|
|
51
|
-
if (comp._N$string !== undefined) comp._N$string = value;
|
|
52
|
-
}
|
|
53
|
-
break;
|
|
54
|
-
case 'fontSize':
|
|
55
|
-
if (comp._fontSize !== undefined) comp._fontSize = value;
|
|
56
|
-
break;
|
|
57
|
-
case 'lineHeight':
|
|
58
|
-
if (comp._lineHeight !== undefined) comp._lineHeight = value;
|
|
59
|
-
break;
|
|
60
|
-
case 'sizeMode':
|
|
61
|
-
if (comp._sizeMode !== undefined) comp._sizeMode = value;
|
|
62
|
-
break;
|
|
63
|
-
case 'horizontalAlign':
|
|
64
|
-
// 支持语义化字符串:left / center / right
|
|
65
|
-
if (comp._N$horizontalAlign !== undefined) {
|
|
66
|
-
comp._N$horizontalAlign = CCLabel.parseHAlign(value);
|
|
67
|
-
} else if (comp._horizontalAlign !== undefined) {
|
|
68
|
-
comp._horizontalAlign = CCLabel.parseHAlign(value);
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
case 'verticalAlign':
|
|
72
|
-
// 支持语义化字符串:top / center / bottom
|
|
73
|
-
if (comp._N$verticalAlign !== undefined) {
|
|
74
|
-
comp._N$verticalAlign = CCLabel.parseVAlign(value);
|
|
75
|
-
} else if (comp._verticalAlign !== undefined) {
|
|
76
|
-
comp._verticalAlign = CCLabel.parseVAlign(value);
|
|
77
|
-
}
|
|
78
|
-
break;
|
|
79
|
-
case 'color':
|
|
80
|
-
// 兼容写法:组件内的 color 同步到节点颜色
|
|
81
|
-
// (Cocos 中文字/富文本颜色本质是节点颜色,不是组件属性)
|
|
82
|
-
if (node) {
|
|
83
|
-
const parsed = parseColor(value);
|
|
84
|
-
if (parsed && node._color) {
|
|
85
|
-
node._color.r = parsed.r;
|
|
86
|
-
node._color.g = parsed.g;
|
|
87
|
-
node._color.b = parsed.b;
|
|
88
|
-
node._color.a = parsed.a;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
default:
|
|
93
|
-
if (comp[key] !== undefined) {
|
|
94
|
-
comp[key] = value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 应用属性到节点
|
|
102
|
-
*/
|
|
103
|
-
function applyNodeProps(node, def) {
|
|
104
|
-
if (def.name) node._name = def.name;
|
|
105
|
-
if (def.active !== undefined) node._active = def.active;
|
|
106
|
-
if (def.opacity !== undefined) node._opacity = def.opacity;
|
|
107
|
-
if (def.width !== undefined) node._contentSize.width = def.width;
|
|
108
|
-
if (def.height !== undefined) node._contentSize.height = def.height;
|
|
109
|
-
if (def.x !== undefined) node._trs.array[0] = def.x;
|
|
110
|
-
if (def.y !== undefined) node._trs.array[1] = def.y;
|
|
111
|
-
if (def.rotation !== undefined) {
|
|
112
|
-
node._trs.array[5] = def.rotation * Math.PI / 180;
|
|
113
|
-
node._eulerAngles.z = def.rotation;
|
|
114
|
-
}
|
|
115
|
-
if (def.scaleX !== undefined) node._trs.array[7] = def.scaleX;
|
|
116
|
-
if (def.scaleY !== undefined) node._trs.array[8] = def.scaleY;
|
|
117
|
-
if (def.anchorX !== undefined) node._anchorPoint.x = def.anchorX;
|
|
118
|
-
if (def.anchorY !== undefined) node._anchorPoint.y = def.anchorY;
|
|
119
|
-
if (def.color) {
|
|
120
|
-
const parsed = parseColor(def.color);
|
|
121
|
-
if (parsed) {
|
|
122
|
-
node._color.set(parsed.r, parsed.g, parsed.b, parsed.a);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* 解析节点定义(递归)
|
|
129
|
-
* @param {Object} def - 节点定义
|
|
130
|
-
* @returns {CCNode}
|
|
131
|
-
*/
|
|
132
|
-
function parseNode(def) {
|
|
133
|
-
const node = new CCNode(def.name || 'Node');
|
|
134
|
-
|
|
135
|
-
// 应用属性
|
|
136
|
-
applyNodeProps(node, def);
|
|
137
|
-
|
|
138
|
-
// 添加组件
|
|
139
|
-
if (def.components && def.components.length > 0) {
|
|
140
|
-
node._components = [];
|
|
141
|
-
for (const compDef of def.components) {
|
|
142
|
-
const parsed = parseComponent(compDef);
|
|
143
|
-
if (parsed) {
|
|
144
|
-
const comp = createComponent(parsed.type);
|
|
145
|
-
if (comp) {
|
|
146
|
-
applyComponentProps(comp, parsed.props, node);
|
|
147
|
-
comp.node = node;
|
|
148
|
-
node._components.push(comp);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// 递归处理子节点
|
|
155
|
-
if (def.children && def.children.length > 0) {
|
|
156
|
-
node._children = [];
|
|
157
|
-
for (const childDef of def.children) {
|
|
158
|
-
const child = parseNode(childDef);
|
|
159
|
-
child._parent = node;
|
|
160
|
-
node._children.push(child);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return node;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 从简化JSON解析为CCNode树
|
|
169
|
-
* @param {Object|string} json - JSON对象或字符串
|
|
170
|
-
* @returns {CCNode}
|
|
171
|
-
*/
|
|
172
|
-
function fromJSON(json) {
|
|
173
|
-
if (typeof json === 'string') {
|
|
174
|
-
json = JSON.parse(json.replace(/^\uFEFF/, '').trim());
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const rootDef = Array.isArray(json) ? json[0] : json;
|
|
178
|
-
return parseNode(rootDef);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
module.exports = {
|
|
182
|
-
fromJSON,
|
|
183
|
-
parseNode,
|
|
184
|
-
applyNodeProps
|
|
185
|
-
};
|
package/src/lib/node-utils.js
DELETED
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 节点工具模块
|
|
3
|
-
* 提供节点创建、属性设置、删除等功能
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { generateId, generateUUID, parseColorToCcColor, colorToHex } = require('./utils');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 创建节点数据
|
|
10
|
-
* @param {string} name - 节点名称
|
|
11
|
-
* @param {number} parentId - 父节点索引
|
|
12
|
-
* @param {object} options - 可选参数
|
|
13
|
-
* @returns {object} 节点数据
|
|
14
|
-
*/
|
|
15
|
-
function createNodeData(name, parentId, options = {}) {
|
|
16
|
-
return {
|
|
17
|
-
"__type__": "cc.Node",
|
|
18
|
-
"_name": name,
|
|
19
|
-
"_objFlags": 0,
|
|
20
|
-
"_parent": { "__id__": parentId },
|
|
21
|
-
"_children": [],
|
|
22
|
-
"_active": options.active !== false,
|
|
23
|
-
"_components": [],
|
|
24
|
-
"_prefab": options._prefab || null,
|
|
25
|
-
"_opacity": options.opacity !== undefined ? options.opacity : 255,
|
|
26
|
-
"_color": parseColorToCcColor(options.color) || {
|
|
27
|
-
"__type__": "cc.Color",
|
|
28
|
-
"r": 255, "g": 255, "b": 255, "a": 255
|
|
29
|
-
},
|
|
30
|
-
"_contentSize": {
|
|
31
|
-
"__type__": "cc.Size",
|
|
32
|
-
"width": options.width || 0,
|
|
33
|
-
"height": options.height || 0
|
|
34
|
-
},
|
|
35
|
-
"_anchorPoint": {
|
|
36
|
-
"__type__": "cc.Vec2",
|
|
37
|
-
"x": options.anchorX !== undefined ? options.anchorX : 0.5,
|
|
38
|
-
"y": options.anchorY !== undefined ? options.anchorY : 0.5
|
|
39
|
-
},
|
|
40
|
-
"_trs": {
|
|
41
|
-
"__type__": "TypedArray",
|
|
42
|
-
"ctor": "Float64Array",
|
|
43
|
-
"array": [
|
|
44
|
-
options.x || 0,
|
|
45
|
-
options.y || 0,
|
|
46
|
-
0, 0, 0,
|
|
47
|
-
(options.rotation || 0) * Math.PI / 180,
|
|
48
|
-
1,
|
|
49
|
-
options.scaleX !== undefined ? options.scaleX : 1,
|
|
50
|
-
options.scaleY !== undefined ? options.scaleY : 1,
|
|
51
|
-
1
|
|
52
|
-
]
|
|
53
|
-
},
|
|
54
|
-
"_eulerAngles": {
|
|
55
|
-
"__type__": "cc.Vec3",
|
|
56
|
-
"x": 0, "y": 0,
|
|
57
|
-
"z": options.rotation || 0
|
|
58
|
-
},
|
|
59
|
-
"_skewX": 0,
|
|
60
|
-
"_skewY": 0,
|
|
61
|
-
"_is3DNode": false,
|
|
62
|
-
"_groupIndex": options.group || 0,
|
|
63
|
-
"groupIndex": options.group || 0,
|
|
64
|
-
"_id": generateUUID()
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 设置节点属性
|
|
70
|
-
* @param {object} node - 节点对象
|
|
71
|
-
* @param {string} key - 属性名
|
|
72
|
-
* @param {*} value - 属性值
|
|
73
|
-
*/
|
|
74
|
-
function setNodeProperty(node, key, value) {
|
|
75
|
-
switch (key) {
|
|
76
|
-
case 'name':
|
|
77
|
-
node._name = value;
|
|
78
|
-
break;
|
|
79
|
-
case 'active':
|
|
80
|
-
node._active = value !== 'false' && value !== false;
|
|
81
|
-
break;
|
|
82
|
-
case 'x':
|
|
83
|
-
case 'y':
|
|
84
|
-
if (!node._trs) {
|
|
85
|
-
node._trs = { "__type__": "TypedArray", "ctor": "Float64Array", "array": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] };
|
|
86
|
-
}
|
|
87
|
-
node._trs.array[key === 'x' ? 0 : 1] = parseFloat(value);
|
|
88
|
-
break;
|
|
89
|
-
case 'width':
|
|
90
|
-
case 'height':
|
|
91
|
-
if (!node._contentSize) {
|
|
92
|
-
node._contentSize = { "__type__": "cc.Size", "width": 0, "height": 0 };
|
|
93
|
-
}
|
|
94
|
-
node._contentSize[key] = parseFloat(value);
|
|
95
|
-
break;
|
|
96
|
-
case 'anchorX':
|
|
97
|
-
case 'anchorY':
|
|
98
|
-
if (!node._anchorPoint) {
|
|
99
|
-
node._anchorPoint = { "__type__": "cc.Vec2", "x": 0.5, "y": 0.5 };
|
|
100
|
-
}
|
|
101
|
-
node._anchorPoint[key === 'anchorX' ? 'x' : 'y'] = parseFloat(value);
|
|
102
|
-
break;
|
|
103
|
-
case 'opacity':
|
|
104
|
-
node._opacity = Math.max(0, Math.min(255, parseInt(value)));
|
|
105
|
-
break;
|
|
106
|
-
case 'color':
|
|
107
|
-
const color = parseColorToCcColor(value);
|
|
108
|
-
if (color) node._color = color;
|
|
109
|
-
break;
|
|
110
|
-
case 'rotation':
|
|
111
|
-
if (!node._eulerAngles) {
|
|
112
|
-
node._eulerAngles = { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": 0 };
|
|
113
|
-
}
|
|
114
|
-
node._eulerAngles.z = parseFloat(value);
|
|
115
|
-
break;
|
|
116
|
-
case 'scaleX':
|
|
117
|
-
case 'scaleY':
|
|
118
|
-
if (!node._trs) {
|
|
119
|
-
node._trs = { "__type__": "TypedArray", "ctor": "Float64Array", "array": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1] };
|
|
120
|
-
}
|
|
121
|
-
node._trs.array[key === 'scaleX' ? 7 : 8] = parseFloat(value);
|
|
122
|
-
break;
|
|
123
|
-
case 'group':
|
|
124
|
-
node._groupIndex = parseInt(value);
|
|
125
|
-
node.groupIndex = node._groupIndex;
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 批量设置节点属性
|
|
132
|
-
* @param {object} node - 节点对象
|
|
133
|
-
* @param {object} options - 属性对象
|
|
134
|
-
*/
|
|
135
|
-
function setNodeProperties(node, options) {
|
|
136
|
-
if (!options) return;
|
|
137
|
-
for (const [key, value] of Object.entries(options)) {
|
|
138
|
-
setNodeProperty(node, key, value);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* 获取节点状态
|
|
144
|
-
* @param {Array} data - 场景/预制体数据数组
|
|
145
|
-
* @param {object} node - 节点对象
|
|
146
|
-
* @param {number} nodeIndex - 节点索引
|
|
147
|
-
* @returns {object} 节点状态
|
|
148
|
-
*/
|
|
149
|
-
function getNodeState(data, node, nodeIndex) {
|
|
150
|
-
const trs = node._trs?.array || [0, 0, 0, 0, 0, 0, 1, 1, 1, 1];
|
|
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
|
-
|
|
164
|
-
const children = (node._children || []).map(ref => data[ref.__id__]?._name || '(unknown)');
|
|
165
|
-
|
|
166
|
-
const result = {
|
|
167
|
-
name: node._name,
|
|
168
|
-
active: node._active,
|
|
169
|
-
position: { x: trs[0], y: trs[1] },
|
|
170
|
-
rotation: node._eulerAngles?.z ?? 0,
|
|
171
|
-
scale: { x: trs[7], y: trs[8] },
|
|
172
|
-
anchor: { x: node._anchorPoint?.x ?? 0.5, y: node._anchorPoint?.y ?? 0.5 },
|
|
173
|
-
size: { w: node._contentSize?.width ?? 0, h: node._contentSize?.height ?? 0 },
|
|
174
|
-
color: colorToHex(node._color),
|
|
175
|
-
opacity: node._opacity ?? 255,
|
|
176
|
-
group: node._groupIndex ?? 0
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
if (children.length > 0) result.children = children;
|
|
180
|
-
if (Object.keys(components).length > 0) result.components = components;
|
|
181
|
-
|
|
182
|
-
return result;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* 收集节点及其所有子节点和组件的索引
|
|
187
|
-
* @param {Array} data - 场景数据
|
|
188
|
-
* @param {number} nodeIndex - 节点索引
|
|
189
|
-
* @param {Set} collected - 已收集的索引集合
|
|
190
|
-
* @returns {Set} 收集的索引集合
|
|
191
|
-
*/
|
|
192
|
-
function collectNodeAndChildren(data, nodeIndex, collected = new Set()) {
|
|
193
|
-
if (collected.has(nodeIndex)) return collected;
|
|
194
|
-
|
|
195
|
-
const node = data[nodeIndex];
|
|
196
|
-
if (!node) return collected;
|
|
197
|
-
|
|
198
|
-
collected.add(nodeIndex);
|
|
199
|
-
|
|
200
|
-
// 收集所有组件
|
|
201
|
-
if (node._components) {
|
|
202
|
-
for (const compRef of node._components) {
|
|
203
|
-
collected.add(compRef.__id__);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// 递归收集子节点
|
|
208
|
-
if (node._children) {
|
|
209
|
-
for (const childRef of node._children) {
|
|
210
|
-
collectNodeAndChildren(data, childRef.__id__, collected);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return collected;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* 从父节点的 _children 中移除节点引用
|
|
219
|
-
* @param {Array} data - 场景数据
|
|
220
|
-
* @param {object} node - 要删除的节点
|
|
221
|
-
* @param {number} nodeIndex - 节点索引
|
|
222
|
-
*/
|
|
223
|
-
function removeFromParent(data, node, nodeIndex) {
|
|
224
|
-
if (node._parent) {
|
|
225
|
-
const parentIndex = node._parent.__id__;
|
|
226
|
-
const parent = data[parentIndex];
|
|
227
|
-
if (parent && parent._children) {
|
|
228
|
-
parent._children = parent._children.filter(c => c.__id__ !== nodeIndex);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* 删除节点
|
|
235
|
-
* @param {Array} data - 场景数据
|
|
236
|
-
* @param {number} nodeIndex - 节点索引
|
|
237
|
-
* @param {Function} rebuildReferences - 重建引用函数
|
|
238
|
-
* @returns {object} 删除结果
|
|
239
|
-
*/
|
|
240
|
-
function deleteNode(data, nodeIndex, rebuildReferences) {
|
|
241
|
-
if (nodeIndex <= 1) {
|
|
242
|
-
return { error: '不能删除根节点' };
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const node = data[nodeIndex];
|
|
246
|
-
if (!node) {
|
|
247
|
-
return { error: `节点索引 ${nodeIndex} 不存在` };
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const nodeName = node._name || '(unnamed)';
|
|
251
|
-
|
|
252
|
-
// 收集所有需要删除的索引
|
|
253
|
-
const indicesToDelete = collectNodeAndChildren(data, nodeIndex);
|
|
254
|
-
|
|
255
|
-
// 从父节点移除引用
|
|
256
|
-
removeFromParent(data, node, nodeIndex);
|
|
257
|
-
|
|
258
|
-
// 重建引用
|
|
259
|
-
rebuildReferences(data, indicesToDelete);
|
|
260
|
-
|
|
261
|
-
// 删除元素(从大到小排序)
|
|
262
|
-
const sortedIndices = Array.from(indicesToDelete).sort((a, b) => b - a);
|
|
263
|
-
for (const idx of sortedIndices) {
|
|
264
|
-
data.splice(idx, 1);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
success: true,
|
|
269
|
-
nodeName,
|
|
270
|
-
nodeIndex,
|
|
271
|
-
deletedCount: sortedIndices.length
|
|
272
|
-
};
|
|
273
|
-
}
|
|
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
|
-
|
|
300
|
-
/**
|
|
301
|
-
* 构建节点树输出
|
|
302
|
-
* @param {Array} data - 场景数据
|
|
303
|
-
* @param {object} scriptMap - 脚本映射
|
|
304
|
-
* @param {number} nodeIndex - 节点索引
|
|
305
|
-
* @param {string} prefix - 前缀
|
|
306
|
-
* @param {boolean} isLast - 是否是最后一个子节点
|
|
307
|
-
* @param {boolean} isRoot - 是否是根节点
|
|
308
|
-
* @returns {string} 树形字符串
|
|
309
|
-
*/
|
|
310
|
-
function buildTree(data, scriptMap, nodeIndex, prefix = '', isLast = true, isRoot = true) {
|
|
311
|
-
const node = data[nodeIndex];
|
|
312
|
-
if (!node) return '';
|
|
313
|
-
|
|
314
|
-
const isSceneRoot = node.__type__ === 'cc.Scene';
|
|
315
|
-
const isPrefabRoot = node.__type__ === 'cc.Prefab';
|
|
316
|
-
const nodeName = node._name || '(unnamed)';
|
|
317
|
-
const active = node._active !== false ? '●' : '○';
|
|
318
|
-
const uuidRegex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
|
|
319
|
-
|
|
320
|
-
let result = '';
|
|
321
|
-
|
|
322
|
-
if (isSceneRoot) {
|
|
323
|
-
result = '[Scene]\n';
|
|
324
|
-
} else if (isPrefabRoot) {
|
|
325
|
-
// 预制体直接显示根节点
|
|
326
|
-
const prefabNode = data[1];
|
|
327
|
-
if (!prefabNode) return '';
|
|
328
|
-
|
|
329
|
-
const prefabActive = prefabNode._active !== false ? '●' : '○';
|
|
330
|
-
result = prefabActive + ' ' + (prefabNode._name || 'Root');
|
|
331
|
-
result += buildComponentInfo(data, prefabNode, scriptMap, uuidRegex);
|
|
332
|
-
result += '\n';
|
|
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);
|
|
346
|
-
result += '\n';
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// 处理子节点
|
|
350
|
-
if (node._children && node._children.length > 0) {
|
|
351
|
-
const childPrefix = prefix + (isSceneRoot ? '' : (isRoot ? '' : (isLast ? ' ' : '│ ')));
|
|
352
|
-
node._children.forEach((childRef, idx) => {
|
|
353
|
-
const childIsLast = idx === node._children.length - 1;
|
|
354
|
-
result += buildTree(data, scriptMap, childRef.__id__, childPrefix, childIsLast, false);
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return result;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* 判断索引指向的是节点还是组件
|
|
363
|
-
* @param {Array} data - 场景数据
|
|
364
|
-
* @param {number} index - 索引
|
|
365
|
-
* @returns {string|null} 'node' 或 'component' 或 null
|
|
366
|
-
*/
|
|
367
|
-
function detectItemType(data, index) {
|
|
368
|
-
const item = data[index];
|
|
369
|
-
if (!item) return null;
|
|
370
|
-
|
|
371
|
-
// 组件有 node 属性指向所属节点
|
|
372
|
-
if (item.node !== undefined) {
|
|
373
|
-
return 'component';
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// 节点有 _name 或类型为 cc.Node/cc.Scene
|
|
377
|
-
const itemType = item.__type__;
|
|
378
|
-
if (itemType === 'cc.Node' || itemType === 'cc.Scene' || item._name !== undefined) {
|
|
379
|
-
return 'node';
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return 'component';
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
module.exports = {
|
|
386
|
-
createNodeData,
|
|
387
|
-
setNodeProperty,
|
|
388
|
-
setNodeProperties,
|
|
389
|
-
getNodeState,
|
|
390
|
-
collectNodeAndChildren,
|
|
391
|
-
removeFromParent,
|
|
392
|
-
deleteNode,
|
|
393
|
-
buildTree,
|
|
394
|
-
detectItemType
|
|
395
|
-
};
|
|
Binary file
|