cocos2d-cli 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +128 -109
- package/src/commands/get.js +113 -18
- package/src/commands/prefab-create.js +43 -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 +1 -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/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
package/src/commands/add.js
CHANGED
|
@@ -1,272 +1,176 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* add 命令 -
|
|
2
|
+
* add 命令 - 添加节点
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const {
|
|
8
|
-
const {
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const { CCNode, CCSceneAsset, CCPrefab, CCCanvas, CCWidget, CCSprite, CCLabel, CCButton } = require('../lib/cc');
|
|
8
|
+
const { buildTree } = require('../lib/node-utils');
|
|
9
|
+
const { loadScriptMap, isPrefab } = require('../lib/fire-utils');
|
|
10
|
+
const { generateCompressedUUID } = require('../lib/utils');
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
|
-
*
|
|
13
|
+
* 解析命令行选项
|
|
12
14
|
*/
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
function parseOptions(args, startIndex) {
|
|
16
|
+
const options = {};
|
|
17
|
+
for (let i = startIndex; i < args.length; i++) {
|
|
18
|
+
const arg = args[i];
|
|
19
|
+
if (arg.startsWith('--')) {
|
|
20
|
+
const eqIndex = arg.indexOf('=');
|
|
21
|
+
if (eqIndex > 0) {
|
|
22
|
+
const key = arg.substring(2, eqIndex);
|
|
23
|
+
let value = arg.substring(eqIndex + 1);
|
|
24
|
+
if (!isNaN(value) && value !== '') {
|
|
25
|
+
value = parseFloat(value);
|
|
26
|
+
}
|
|
27
|
+
options[key] = value;
|
|
28
|
+
}
|
|
18
29
|
}
|
|
19
30
|
}
|
|
20
|
-
return
|
|
31
|
+
return options;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
/**
|
|
24
|
-
*
|
|
35
|
+
* 创建组件
|
|
25
36
|
*/
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const childEnd = getSubtreeEndIndex(data, childRef.__id__);
|
|
35
|
-
lastIndex = Math.max(lastIndex, childEnd);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (node._components) {
|
|
40
|
-
for (const compRef of node._components) {
|
|
41
|
-
lastIndex = Math.max(lastIndex, compRef.__id__);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (node._prefab && nodeIndex !== 1) {
|
|
46
|
-
lastIndex = Math.max(lastIndex, node._prefab.__id__);
|
|
37
|
+
function createComponent(type) {
|
|
38
|
+
switch (type.toLowerCase()) {
|
|
39
|
+
case 'canvas': return new CCCanvas();
|
|
40
|
+
case 'widget': return new CCWidget();
|
|
41
|
+
case 'sprite': return new CCSprite();
|
|
42
|
+
case 'label': return new CCLabel();
|
|
43
|
+
case 'button': return new CCButton();
|
|
44
|
+
default: return null;
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
return lastIndex;
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
/**
|
|
53
|
-
*
|
|
49
|
+
* 查找节点
|
|
54
50
|
*/
|
|
55
|
-
function
|
|
56
|
-
|
|
51
|
+
function findNode(root, path) {
|
|
52
|
+
if (!path) return root;
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
indexMap[oldIndex] = oldIndex;
|
|
61
|
-
} else {
|
|
62
|
-
indexMap[oldIndex] = oldIndex + count;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
54
|
+
const parts = path.split('/').filter(p => p);
|
|
55
|
+
if (parts.length === 0) return root;
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (indexMap[oldId] !== undefined) {
|
|
72
|
-
obj.__id__ = indexMap[oldId];
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
for (const key of Object.keys(obj)) {
|
|
76
|
-
updateRef(obj[key]);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
57
|
+
let current = root;
|
|
58
|
+
|
|
59
|
+
// 如果路径以根节点名称开始,跳过
|
|
60
|
+
if (parts[0] === root._name) {
|
|
61
|
+
parts.shift();
|
|
79
62
|
}
|
|
80
63
|
|
|
81
|
-
for (const
|
|
82
|
-
|
|
64
|
+
for (const part of parts) {
|
|
65
|
+
if (!current._children || current._children.length === 0) return null;
|
|
66
|
+
const found = current._children.find(c => c._name === part);
|
|
67
|
+
if (!found) return null;
|
|
68
|
+
current = found;
|
|
83
69
|
}
|
|
84
70
|
|
|
85
|
-
return
|
|
71
|
+
return current;
|
|
86
72
|
}
|
|
87
73
|
|
|
88
74
|
function run(args) {
|
|
89
75
|
if (args.length < 3) {
|
|
90
|
-
|
|
76
|
+
console.log(JSON.stringify({ error: '用法: cocos2d-cli add <场景.fire|预制体.prefab> <父节点路径> <节点名称> [--type=组件类型] [--x=N] [--y=N]' }));
|
|
91
77
|
return;
|
|
92
78
|
}
|
|
93
79
|
|
|
94
80
|
const filePath = args[0];
|
|
95
|
-
const
|
|
81
|
+
const parentPath = args[1];
|
|
96
82
|
const nodeName = args[2];
|
|
97
|
-
|
|
98
83
|
const options = parseOptions(args, 3);
|
|
99
84
|
|
|
100
|
-
|
|
101
|
-
if (options.x) options.x = parseFloat(options.x) || 0;
|
|
102
|
-
if (options.y) options.y = parseFloat(options.y) || 0;
|
|
103
|
-
if (options.width) options.width = parseFloat(options.width) || 0;
|
|
104
|
-
if (options.height) options.height = parseFloat(options.height) || 0;
|
|
105
|
-
if (options.at !== undefined) options.at = parseInt(options.at);
|
|
106
|
-
if (options.active !== undefined) options.active = options.active !== 'false';
|
|
107
|
-
if (options.fontSize) options.fontSize = parseInt(options.fontSize) || 40;
|
|
85
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
108
86
|
|
|
109
87
|
try {
|
|
110
|
-
|
|
111
|
-
|
|
88
|
+
let root;
|
|
89
|
+
let asset;
|
|
90
|
+
const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
112
91
|
|
|
113
|
-
if (
|
|
114
|
-
|
|
92
|
+
if (ext === '.fire') {
|
|
93
|
+
asset = CCSceneAsset.fromJSON(json);
|
|
94
|
+
root = asset._scene;
|
|
95
|
+
} else if (ext === '.prefab') {
|
|
96
|
+
asset = CCPrefab.fromJSON(json);
|
|
97
|
+
root = asset._root;
|
|
98
|
+
} else {
|
|
99
|
+
console.log(JSON.stringify({ error: '不支持的文件类型,仅支持 .fire 和 .prefab' }));
|
|
115
100
|
return;
|
|
116
101
|
}
|
|
117
102
|
|
|
118
|
-
const
|
|
103
|
+
const parent = findNode(root, parentPath);
|
|
119
104
|
|
|
120
|
-
if (
|
|
121
|
-
|
|
105
|
+
if (!parent) {
|
|
106
|
+
console.log(JSON.stringify({ error: `父节点不存在: ${parentPath}` }));
|
|
122
107
|
return;
|
|
123
108
|
}
|
|
124
109
|
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
// 确定插入位置
|
|
129
|
-
let insertIndex;
|
|
110
|
+
// 创建节点
|
|
111
|
+
const node = new CCNode(nodeName);
|
|
130
112
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
113
|
+
// 应用属性
|
|
114
|
+
if (options.x !== undefined) node._trs.array[0] = parseFloat(options.x);
|
|
115
|
+
if (options.y !== undefined) node._trs.array[1] = parseFloat(options.y);
|
|
116
|
+
if (options.width !== undefined) node._contentSize.width = parseFloat(options.width);
|
|
117
|
+
if (options.height !== undefined) node._contentSize.height = parseFloat(options.height);
|
|
118
|
+
if (options.scaleX !== undefined) node._trs.array[7] = parseFloat(options.scaleX);
|
|
119
|
+
if (options.scaleY !== undefined) node._trs.array[8] = parseFloat(options.scaleY);
|
|
120
|
+
if (options.rotation !== undefined) {
|
|
121
|
+
node._trs.array[5] = parseFloat(options.rotation) * Math.PI / 180;
|
|
122
|
+
node._eulerAngles.z = parseFloat(options.rotation);
|
|
123
|
+
}
|
|
124
|
+
if (options.active !== undefined) {
|
|
125
|
+
node._active = options.active !== 'false' && options.active !== false;
|
|
144
126
|
}
|
|
145
127
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (options.type) {
|
|
159
|
-
compData = createComponent(options.type, insertIndex);
|
|
160
|
-
if (compData) {
|
|
161
|
-
if (options.type === 'label') {
|
|
162
|
-
if (options.fontSize) {
|
|
163
|
-
compData._fontSize = options.fontSize;
|
|
164
|
-
compData._lineHeight = options.fontSize;
|
|
165
|
-
}
|
|
166
|
-
if (options.string) {
|
|
167
|
-
compData._string = options.string;
|
|
168
|
-
compData._N$string = options.string;
|
|
169
|
-
}
|
|
128
|
+
// 添加组件
|
|
129
|
+
if (options.type) {
|
|
130
|
+
const comp = createComponent(options.type);
|
|
131
|
+
if (comp) {
|
|
132
|
+
comp.node = node;
|
|
133
|
+
node._components = [comp];
|
|
134
|
+
|
|
135
|
+
// 组件特殊属性
|
|
136
|
+
if (options.type.toLowerCase() === 'label') {
|
|
137
|
+
if (options.string) {
|
|
138
|
+
comp._string = options.string;
|
|
139
|
+
comp['_N$string'] = options.string;
|
|
170
140
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
// 创建 PrefabInfo
|
|
175
|
-
const prefabInfo = {
|
|
176
|
-
"__type__": "cc.PrefabInfo",
|
|
177
|
-
"root": { "__id__": 1 },
|
|
178
|
-
"asset": { "__id__": 0 },
|
|
179
|
-
"fileId": generateFileId(),
|
|
180
|
-
"sync": false
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const itemsToInsert = [nodeData];
|
|
184
|
-
if (compData) itemsToInsert.push(compData);
|
|
185
|
-
itemsToInsert.push(prefabInfo);
|
|
186
|
-
|
|
187
|
-
if (isRootChild) {
|
|
188
|
-
if (insertIndex > rootPrefabInfoOldIdx) {
|
|
189
|
-
insertIndex--;
|
|
190
|
-
}
|
|
191
|
-
data.splice(rootPrefabInfoOldIdx, 1);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
for (let i = 0; i < itemsToInsert.length; i++) {
|
|
195
|
-
data.splice(insertIndex + i, 0, itemsToInsert[i]);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
rebuildReferencesForInsert(data, insertIndex, itemsToInsert.length);
|
|
199
|
-
|
|
200
|
-
newNodeIndex = insertIndex;
|
|
201
|
-
|
|
202
|
-
if (compData) {
|
|
203
|
-
compData.node = { "__id__": newNodeIndex };
|
|
204
|
-
nodeData._components.push({ "__id__": newNodeIndex + 1 });
|
|
205
|
-
nodeData._prefab = { "__id__": newNodeIndex + 2 };
|
|
206
|
-
} else {
|
|
207
|
-
nodeData._prefab = { "__id__": newNodeIndex + 1 };
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (isRootChild) {
|
|
211
|
-
data.push(rootPrefabInfo);
|
|
212
|
-
data[1]._prefab = { "__id__": data.length - 1 };
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
} else {
|
|
216
|
-
// 场景模式
|
|
217
|
-
const newNode = createNodeData(nodeName, parentIndex, options);
|
|
218
|
-
|
|
219
|
-
const itemsToInsert = [newNode];
|
|
220
|
-
|
|
221
|
-
let compData = null;
|
|
222
|
-
if (options.type) {
|
|
223
|
-
compData = createComponent(options.type, insertIndex);
|
|
224
|
-
if (compData) {
|
|
225
|
-
if (options.type === 'label') {
|
|
226
|
-
if (options.fontSize) {
|
|
227
|
-
compData._fontSize = options.fontSize;
|
|
228
|
-
compData._lineHeight = options.fontSize;
|
|
229
|
-
}
|
|
230
|
-
if (options.string) {
|
|
231
|
-
compData._string = options.string;
|
|
232
|
-
compData._N$string = options.string;
|
|
233
|
-
}
|
|
141
|
+
if (options.fontSize) {
|
|
142
|
+
comp._fontSize = parseInt(options.fontSize);
|
|
143
|
+
comp._lineHeight = parseInt(options.fontSize);
|
|
234
144
|
}
|
|
235
145
|
}
|
|
236
|
-
if (compData) itemsToInsert.push(compData);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
for (let i = 0; i < itemsToInsert.length; i++) {
|
|
240
|
-
data.splice(insertIndex + i, 0, itemsToInsert[i]);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
rebuildReferencesForInsert(data, insertIndex, itemsToInsert.length);
|
|
244
|
-
|
|
245
|
-
newNodeIndex = insertIndex;
|
|
246
|
-
|
|
247
|
-
if (compData) {
|
|
248
|
-
compData.node = { "__id__": newNodeIndex };
|
|
249
|
-
newNode._components.push({ "__id__": newNodeIndex + 1 });
|
|
250
146
|
}
|
|
251
147
|
}
|
|
252
148
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
149
|
+
// 添加节点到父节点
|
|
150
|
+
parent._children = parent._children || [];
|
|
151
|
+
parent._children.push(node);
|
|
152
|
+
node._parent = parent;
|
|
153
|
+
|
|
154
|
+
// 场景节点需要 _id,预制体需要 PrefabInfo
|
|
155
|
+
if (ext === '.fire') {
|
|
156
|
+
node._id = generateCompressedUUID();
|
|
157
|
+
} else if (ext === '.prefab') {
|
|
158
|
+
const { CCPrefabInfo } = require('../lib/cc');
|
|
159
|
+
node._prefab = new CCPrefabInfo();
|
|
160
|
+
}
|
|
257
161
|
|
|
258
|
-
|
|
259
|
-
|
|
162
|
+
// 保存
|
|
163
|
+
const data = asset.toJSON();
|
|
164
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
|
|
260
165
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
});
|
|
166
|
+
// 输出节点树
|
|
167
|
+
const scriptMap = loadScriptMap(filePath);
|
|
168
|
+
const prefab = isPrefab(data);
|
|
169
|
+
const startIndex = prefab ? 0 : 1;
|
|
170
|
+
console.log(buildTree(data, scriptMap, startIndex).trim());
|
|
267
171
|
|
|
268
172
|
} catch (err) {
|
|
269
|
-
|
|
173
|
+
console.log(JSON.stringify({ error: err.message }));
|
|
270
174
|
}
|
|
271
175
|
}
|
|
272
176
|
|