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.
Files changed (62) hide show
  1. package/data/script_map.json +25 -25
  2. package/dist/bin/cocos2d-cli.js +64 -0
  3. package/dist/src/commands/add-component.js +3 -0
  4. package/dist/src/commands/add.js +3 -0
  5. package/dist/src/commands/build.js +6 -0
  6. package/dist/src/commands/create-scene.js +3 -0
  7. package/dist/src/commands/get.js +3 -0
  8. package/dist/src/commands/prefab-create.js +109 -0
  9. package/dist/src/commands/remove-component.js +3 -0
  10. package/dist/src/commands/remove.js +3 -0
  11. package/dist/src/commands/screenshot.js +41 -0
  12. package/dist/src/commands/set-component.js +3 -0
  13. package/dist/src/commands/set.js +3 -0
  14. package/dist/src/commands/tree.js +24 -0
  15. package/{src → dist/src}/lib/cc/CCButton.js +26 -33
  16. package/{src → dist/src}/lib/cc/CCCamera.js +20 -30
  17. package/{src → dist/src}/lib/cc/CCCanvas.js +10 -15
  18. package/{src → dist/src}/lib/cc/CCColor.js +6 -8
  19. package/{src → dist/src}/lib/cc/CCComponent.js +8 -29
  20. package/{src → dist/src}/lib/cc/CCLabel.js +44 -51
  21. package/{src → dist/src}/lib/cc/CCNode.js +52 -118
  22. package/{src → dist/src}/lib/cc/CCObject.js +4 -8
  23. package/{src → dist/src}/lib/cc/CCPrefab.js +77 -100
  24. package/{src → dist/src}/lib/cc/CCRect.js +6 -8
  25. package/{src → dist/src}/lib/cc/CCRichText.js +10 -16
  26. package/{src → dist/src}/lib/cc/CCScene.js +3 -13
  27. package/dist/src/lib/cc/CCSceneAsset.js +242 -0
  28. package/{src → dist/src}/lib/cc/CCSize.js +4 -8
  29. package/{src → dist/src}/lib/cc/CCSprite.js +21 -33
  30. package/{src → dist/src}/lib/cc/CCTrs.js +4 -29
  31. package/{src → dist/src}/lib/cc/CCVec2.js +4 -8
  32. package/{src → dist/src}/lib/cc/CCVec3.js +5 -8
  33. package/{src → dist/src}/lib/cc/CCWidget.js +20 -24
  34. package/dist/src/lib/fire-utils.js +86 -0
  35. package/dist/src/lib/json-parser.js +114 -0
  36. package/dist/src/lib/node-utils.js +131 -0
  37. package/{src → dist/src}/lib/screenshot-core.js +54 -119
  38. package/dist/src/lib/templates.js +17 -0
  39. package/dist/src/lib/utils.js +81 -0
  40. package/package.json +40 -33
  41. package/bin/cocos2d-cli.js +0 -152
  42. package/src/commands/add-component.js +0 -112
  43. package/src/commands/add.js +0 -177
  44. package/src/commands/build.js +0 -78
  45. package/src/commands/create-scene.js +0 -181
  46. package/src/commands/get.js +0 -108
  47. package/src/commands/prefab-create.js +0 -111
  48. package/src/commands/remove-component.js +0 -111
  49. package/src/commands/remove.js +0 -99
  50. package/src/commands/screenshot.js +0 -108
  51. package/src/commands/set-component.js +0 -119
  52. package/src/commands/set.js +0 -107
  53. package/src/commands/tree.js +0 -29
  54. package/src/lib/cc/CCSceneAsset.js +0 -303
  55. package/src/lib/cc/index.js +0 -42
  56. package/src/lib/fire-utils.js +0 -374
  57. package/src/lib/json-parser.js +0 -185
  58. package/src/lib/node-utils.js +0 -395
  59. package/src/lib/screenshot/favicon.ico +0 -0
  60. package/src/lib/screenshot/index.html +0 -30
  61. package/src/lib/templates.js +0 -49
  62. package/src/lib/utils.js +0 -202
@@ -1,18 +1,10 @@
1
- /**
2
- * Screenshot Core Module
3
- * 渲染 JSON 数据并使用 Playwright 截图
4
- */
5
-
6
- const { chromium } = require('playwright');
7
- const fs = require('fs').promises;
8
- const path = require('path');
9
- const http = require('http');
10
- const url = require('url');
11
- const os = require('os');
12
-
13
- // 默认配置
1
+ import { chromium } from 'playwright';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ import * as http from 'http';
5
+ import { fileURLToPath } from 'url';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
7
  const DEFAULT_CONFIG = {
15
- jsonPath: null,
16
8
  outputDir: process.cwd(),
17
9
  viewport: { width: 750, height: 1334 },
18
10
  fullPage: true,
@@ -20,32 +12,27 @@ const DEFAULT_CONFIG = {
20
12
  timeout: 30000,
21
13
  waitTime: 1000
22
14
  };
23
-
24
- // 获取内置资源目录
25
15
  function getAssetsDir() {
26
- return path.join(__dirname, 'screenshot');
16
+ const projectRoot = process.cwd();
17
+ return path.join(projectRoot, 'src', 'lib', 'screenshot');
27
18
  }
28
-
29
- // 创建临时工作目录
30
19
  async function createTempWorkDir() {
31
- const tempBase = os.tmpdir();
20
+ const tempBase = process.env.TEMP || process.env.TMP || '/tmp';
32
21
  const timestamp = Date.now();
33
22
  const tempDir = path.join(tempBase, `cocos2d-screenshot-${timestamp}`);
34
23
  await fs.mkdir(tempDir, { recursive: true });
35
24
  return tempDir;
36
25
  }
37
-
38
- // 复制内置资源到临时目录
39
26
  async function copyBuiltInAssets(tempDir, logs) {
40
27
  const assetsDir = getAssetsDir();
41
28
  const assets = ['index.html', 'favicon.ico'];
42
-
43
29
  for (const asset of assets) {
44
30
  const src = path.join(assetsDir, asset);
45
31
  const dest = path.join(tempDir, asset);
46
32
  try {
47
33
  await fs.copyFile(src, dest);
48
- } catch (err) {
34
+ }
35
+ catch (err) {
49
36
  logs.push({
50
37
  timestamp: new Date().toISOString(),
51
38
  type: 'warning',
@@ -54,21 +41,16 @@ async function copyBuiltInAssets(tempDir, logs) {
54
41
  }
55
42
  }
56
43
  }
57
-
58
- // 静态文件服务器
59
44
  async function startServer(staticDir, logs) {
60
45
  return new Promise((resolve, reject) => {
61
46
  const server = http.createServer(async (req, res) => {
62
47
  try {
63
- const parsedUrl = url.parse(req.url);
64
- let filePath = path.join(staticDir, parsedUrl.pathname);
65
-
66
- if (parsedUrl.pathname === '/') {
48
+ const reqUrl = new URL(req.url || '/', `http://${req.headers.host}`);
49
+ let filePath = path.join(staticDir, reqUrl.pathname);
50
+ if (reqUrl.pathname === '/') {
67
51
  filePath = path.join(staticDir, 'index.html');
68
52
  }
69
-
70
53
  const data = await fs.readFile(filePath);
71
-
72
54
  const ext = path.extname(filePath).toLowerCase();
73
55
  const contentTypes = {
74
56
  '.html': 'text/html',
@@ -86,18 +68,18 @@ async function startServer(staticDir, logs) {
86
68
  '.txt': 'text/plain',
87
69
  '.xml': 'application/xml'
88
70
  };
89
-
90
- res.writeHead(200, {
71
+ res.writeHead(200, {
91
72
  'Content-Type': contentTypes[ext] || 'application/octet-stream',
92
73
  'Access-Control-Allow-Origin': '*'
93
74
  });
94
75
  res.end(data);
95
-
96
- } catch (err) {
76
+ }
77
+ catch (err) {
97
78
  if (err.code === 'ENOENT') {
98
79
  res.writeHead(404);
99
80
  res.end();
100
- } else {
81
+ }
82
+ else {
101
83
  logs.push({
102
84
  timestamp: new Date().toISOString(),
103
85
  type: 'server-error',
@@ -108,16 +90,14 @@ async function startServer(staticDir, logs) {
108
90
  }
109
91
  }
110
92
  });
111
-
112
93
  server.listen(0, '127.0.0.1', () => resolve(server));
113
94
  });
114
95
  }
115
-
116
- // 递归删除目录
117
96
  async function removeDir(dirPath, logs) {
118
97
  try {
119
98
  await fs.rm(dirPath, { recursive: true, force: true });
120
- } catch (err) {
99
+ }
100
+ catch (err) {
121
101
  if (logs) {
122
102
  logs.push({
123
103
  timestamp: new Date().toISOString(),
@@ -127,32 +107,17 @@ async function removeDir(dirPath, logs) {
127
107
  }
128
108
  }
129
109
  }
130
-
131
- /**
132
- * 截图核心函数
133
- * @param {Object} userConfig - 配置选项
134
- * @param {string} userConfig.jsonPath - JSON 文件路径
135
- * @param {string} userConfig.outputDir - 输出目录
136
- * @param {Object} userConfig.viewport - 视口大小 {width, height}
137
- * @param {boolean} userConfig.fullPage - 是否全页截图
138
- * @param {number} userConfig.timeout - 超时时间(毫秒)
139
- * @param {number} userConfig.waitTime - 等待时间(毫秒)
140
- * @returns {Promise<{screenshotPath: string, logs: Array}>}
141
- */
142
- async function takeScreenshot(userConfig = {}) {
110
+ export async function takeScreenshot(userConfig = {}) {
143
111
  const config = { ...DEFAULT_CONFIG, ...userConfig };
144
-
145
112
  if (!config.jsonPath) {
146
113
  throw new Error('JSON file path is required');
147
114
  }
148
-
149
115
  let server = null;
150
116
  let browser = null;
151
117
  let tempDir = null;
152
118
  const logs = [];
153
119
  let screenshotPath = null;
154
120
  let logDir = null;
155
-
156
121
  const addLog = (type, text, extra = {}) => {
157
122
  logs.push({
158
123
  timestamp: new Date().toISOString(),
@@ -161,70 +126,47 @@ async function takeScreenshot(userConfig = {}) {
161
126
  ...extra
162
127
  });
163
128
  };
164
-
165
129
  try {
166
130
  const timestamp = Date.now();
167
-
168
- // 检查 JSON 文件是否存在
169
131
  try {
170
132
  await fs.access(config.jsonPath);
171
- } catch (error) {
133
+ }
134
+ catch (error) {
172
135
  throw new Error(`JSON file not found: ${config.jsonPath}`);
173
136
  }
174
-
175
- // 确保输出目录存在
176
137
  await fs.mkdir(config.outputDir, { recursive: true });
177
-
178
- // 创建临时工作目录
179
138
  tempDir = await createTempWorkDir();
180
139
  addLog('info', `Temp dir: ${tempDir}`);
181
-
182
- // 复制内置资源到临时目录
183
140
  await copyBuiltInAssets(tempDir, logs);
184
-
185
- // 复制用户的 JSON 文件到临时目录
186
141
  const destJsonPath = path.join(tempDir, 'data.json');
187
142
  await fs.copyFile(config.jsonPath, destJsonPath);
188
143
  addLog('info', `JSON: ${config.jsonPath}`);
189
-
190
- // 截图输出路径
191
144
  screenshotPath = path.join(config.outputDir, `screenshot-${timestamp}.png`);
192
-
193
- // 启动HTTP服务器
194
145
  addLog('info', 'Starting Server');
195
146
  server = await startServer(tempDir, logs);
196
- const serverUrl = `http://127.0.0.1:${server.address().port}`;
147
+ const address = server.address();
148
+ const serverUrl = `http://127.0.0.1:${address.port}`;
197
149
  addLog('info', `Server: ${serverUrl}`);
198
-
199
- // 启动浏览器
200
150
  addLog('info', 'Launching Browser');
201
151
  browser = await chromium.launch({
202
- headless: true,
203
- channel: 'chrome'
152
+ headless: true
204
153
  });
205
154
  addLog('info', 'Browser launched');
206
-
207
155
  const page = await browser.newPage({
208
156
  viewport: config.viewport
209
157
  });
210
-
211
- // 监听浏览器控制台日志
212
- page.on('console', msg => {
158
+ page.on('console', (msg) => {
213
159
  const text = msg.text();
214
160
  addLog(msg.type(), text);
215
161
  });
216
-
217
- page.on('pageerror', error => {
162
+ page.on('pageerror', (error) => {
218
163
  addLog('pageerror', error.message);
219
164
  });
220
-
221
- page.on('requestfailed', request => {
165
+ page.on('requestfailed', (request) => {
222
166
  const failure = request.failure();
223
167
  const errorText = failure ? failure.errorText : 'Unknown error';
224
168
  addLog('requestfailed', request.url(), { error: errorText });
225
169
  });
226
-
227
- // 加载页面
228
170
  addLog('info', 'Loading Page');
229
171
  const pageUrl = config.debugBounds
230
172
  ? `${serverUrl}/index.html?debugBounds=true`
@@ -234,13 +176,9 @@ async function takeScreenshot(userConfig = {}) {
234
176
  timeout: config.timeout
235
177
  });
236
178
  addLog('info', 'Page loaded');
237
-
238
- // 等待渲染
239
179
  addLog('info', 'Waiting for Render');
240
180
  await page.waitForTimeout(config.waitTime);
241
181
  addLog('info', 'Wait complete');
242
-
243
- // 截图
244
182
  addLog('info', 'Taking Screenshot');
245
183
  await page.screenshot({
246
184
  path: screenshotPath,
@@ -248,39 +186,36 @@ async function takeScreenshot(userConfig = {}) {
248
186
  });
249
187
  addLog('info', `Screenshot saved: ${screenshotPath}`);
250
188
  addLog('info', 'Done');
251
-
252
189
  return { screenshotPath, logs };
253
-
254
- } catch (error) {
190
+ }
191
+ catch (error) {
255
192
  addLog('error', error.message);
256
193
  try {
257
194
  logDir = path.join(config.outputDir, `screenshot-logs-${Date.now()}`);
258
195
  await fs.mkdir(logDir, { recursive: true });
259
- await fs.writeFile(
260
- path.join(logDir, 'logs.json'),
261
- JSON.stringify({
262
- error: error.message,
263
- jsonPath: config.jsonPath,
264
- outputDir: config.outputDir,
265
- viewport: config.viewport,
266
- fullPage: config.fullPage,
267
- debugBounds: config.debugBounds,
268
- timeout: config.timeout,
269
- waitTime: config.waitTime,
270
- screenshotPath,
271
- logs
272
- }, null, 2),
273
- 'utf8'
274
- );
275
- } catch (_) {}
196
+ await fs.writeFile(path.join(logDir, 'logs.json'), JSON.stringify({
197
+ error: error.message,
198
+ jsonPath: config.jsonPath,
199
+ outputDir: config.outputDir,
200
+ viewport: config.viewport,
201
+ fullPage: config.fullPage,
202
+ debugBounds: config.debugBounds,
203
+ timeout: config.timeout,
204
+ waitTime: config.waitTime,
205
+ screenshotPath,
206
+ logs
207
+ }, null, 2), 'utf8');
208
+ }
209
+ catch (_) { }
276
210
  error.logDir = logDir;
277
211
  throw error;
278
- } finally {
279
- // 清理资源
280
- if (browser) await browser.close().catch(() => {});
281
- if (server) server.close();
282
- if (tempDir) await removeDir(tempDir, logs);
212
+ }
213
+ finally {
214
+ if (browser)
215
+ await browser.close().catch(() => { });
216
+ if (server)
217
+ server.close();
218
+ if (tempDir)
219
+ await removeDir(tempDir, logs);
283
220
  }
284
221
  }
285
-
286
- module.exports = { takeScreenshot };
@@ -0,0 +1,17 @@
1
+ import CCNode from './cc/CCNode.js';
2
+ import CCScene from './cc/CCScene.js';
3
+ import CCSceneAsset from './cc/CCSceneAsset.js';
4
+ import { CCPrefab, CCPrefabInfo } from './cc/CCPrefab.js';
5
+ export function createPrefab(name = 'Prefab') {
6
+ const prefab = new CCPrefab();
7
+ const root = new CCNode(name);
8
+ prefab.setRoot(root);
9
+ return prefab;
10
+ }
11
+ export function createScene(name = 'NewScene') {
12
+ const asset = new CCSceneAsset();
13
+ const scene = new CCScene(name);
14
+ asset._scene = scene;
15
+ return asset;
16
+ }
17
+ export { CCNode, CCScene, CCSceneAsset, CCPrefab, CCPrefabInfo };
@@ -0,0 +1,81 @@
1
+ import * as crypto from 'crypto';
2
+ export function parseColor(color) {
3
+ if (!color)
4
+ return null;
5
+ if (color.startsWith('#')) {
6
+ const hex = color.slice(1);
7
+ if (hex.length === 6 || hex.length === 8) {
8
+ return {
9
+ r: parseInt(hex.slice(0, 2), 16),
10
+ g: parseInt(hex.slice(2, 4), 16),
11
+ b: parseInt(hex.slice(4, 6), 16),
12
+ a: hex.length === 8 ? parseInt(hex.slice(6, 8), 16) : 255
13
+ };
14
+ }
15
+ }
16
+ const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
17
+ if (rgbMatch) {
18
+ return {
19
+ r: parseInt(rgbMatch[1]),
20
+ g: parseInt(rgbMatch[2]),
21
+ b: parseInt(rgbMatch[3]),
22
+ a: rgbMatch[4] ? Math.round(parseFloat(rgbMatch[4]) * 255) : 255
23
+ };
24
+ }
25
+ return null;
26
+ }
27
+ export function parseColorToCcColor(color) {
28
+ const parsed = parseColor(color);
29
+ if (!parsed)
30
+ return null;
31
+ return { __type__: 'cc.Color', ...parsed };
32
+ }
33
+ export function colorToHex(r, g, b, a = 255) {
34
+ return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}${a !== 255 ? a.toString(16).padStart(2, '0') : ''}`;
35
+ }
36
+ export function generateUUID() {
37
+ return crypto.randomUUID().replace(/-/g, '');
38
+ }
39
+ export function compressUUID(uuid) {
40
+ const hex = uuid.replace(/-/g, '');
41
+ const bytes = Buffer.from(hex, 'hex');
42
+ return bytes.toString('base64url').slice(0, 22);
43
+ }
44
+ export function generateCompressedUUID() {
45
+ return compressUUID(generateUUID());
46
+ }
47
+ export function generateId() {
48
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
49
+ let result = '';
50
+ for (let i = 0; i < 22; i++) {
51
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
52
+ }
53
+ return result;
54
+ }
55
+ export function parseOptions(args) {
56
+ const options = {};
57
+ for (let i = 0; i < args.length; i++) {
58
+ const arg = args[i];
59
+ if (arg.startsWith('--')) {
60
+ const key = arg.slice(2);
61
+ const nextArg = args[i + 1];
62
+ if (nextArg && !nextArg.startsWith('--')) {
63
+ options[key] = nextArg;
64
+ i++;
65
+ }
66
+ else {
67
+ options[key] = true;
68
+ }
69
+ }
70
+ }
71
+ return options;
72
+ }
73
+ export function outputJson(data) {
74
+ console.log(JSON.stringify(data, null, 2));
75
+ }
76
+ export function outputError(message) {
77
+ console.log(JSON.stringify({ error: message }));
78
+ }
79
+ export function outputSuccess(message) {
80
+ console.log(JSON.stringify({ success: message }));
81
+ }
package/package.json CHANGED
@@ -1,33 +1,40 @@
1
- {
2
- "name": "cocos2d-cli",
3
- "version": "1.6.4",
4
- "description": "Command-line tools for AI to read and manipulate Cocos Creator 2.4.x project scenes",
5
- "main": "bin/cocos2d-cli.js",
6
- "bin": {
7
- "cocos2d-cli": "bin/cocos2d-cli.js"
8
- },
9
- "files": [
10
- "bin",
11
- "src",
12
- "data"
13
- ],
14
- "scripts": {
15
- "test": "echo \"No tests specified\" && exit 1"
16
- },
17
- "keywords": [
18
- "cocos",
19
- "cocos-creator",
20
- "cli",
21
- "scene",
22
- "fire",
23
- "screenshot"
24
- ],
25
- "author": "",
26
- "license": "MIT",
27
- "engines": {
28
- "node": ">=14.0.0"
29
- },
30
- "dependencies": {
31
- "playwright": "^1.58.2"
32
- }
33
- }
1
+ {
2
+ "name": "cocos2d-cli",
3
+ "version": "2.0.0",
4
+ "description": "Command-line tools for AI to read and manipulate Cocos Creator 2.4.x project scenes",
5
+ "type": "module",
6
+ "main": "dist/bin/cocos2d-cli.js",
7
+ "bin": {
8
+ "cocos2d-cli": "dist/bin/cocos2d-cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "data"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "watch": "tsc --watch",
17
+ "prepare": "npm run build",
18
+ "test": "echo \"No tests specified\" && exit 1"
19
+ },
20
+ "keywords": [
21
+ "cocos",
22
+ "cocos-creator",
23
+ "cli",
24
+ "scene",
25
+ "fire",
26
+ "screenshot"
27
+ ],
28
+ "author": "",
29
+ "license": "MIT",
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "dependencies": {
34
+ "playwright": "^1.58.2"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.15.17",
38
+ "typescript": "^5.9.3"
39
+ }
40
+ }
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Cocos Creator CLI
4
- * Command-line tools for AI to read and manipulate Cocos Creator 2.4.x project scenes
5
- */
6
-
7
- const path = require('path');
8
-
9
- // 命令映射
10
- const commands = {
11
- tree: '../src/commands/tree',
12
- get: '../src/commands/get',
13
- set: '../src/commands/set',
14
- 'set-component': '../src/commands/set-component',
15
- add: '../src/commands/add',
16
- 'add-component': '../src/commands/add-component',
17
- 'remove-component': '../src/commands/remove-component',
18
- 'remove': '../src/commands/remove',
19
- build: '../src/commands/build',
20
- 'create-prefab': '../src/commands/prefab-create',
21
- 'create-scene': '../src/commands/create-scene',
22
- 'screenshot': '../src/commands/screenshot'
23
- };
24
-
25
- // 帮助信息
26
- function showHelp() {
27
- console.log(`
28
- Cocos Creator CLI - 场景/预制体操作工具集
29
-
30
- 用法:
31
- cocos2d-cli <command> [options]
32
-
33
- 命令:
34
- tree <场景.fire | 预制体.prefab> 查看节点树
35
- get <场景.fire | 预制体.prefab> <节点路径> [属性名|组件类型] 获取节点或组件属性
36
- set <场景.fire | 预制体.prefab> <节点路径> <属性名> <值> 修改节点属性
37
- set-component <文件> <节点路径> <组件类型> <属性名> <值> 修改组件属性
38
- add <场景.fire | 预制体.prefab> <父节点路径> <名称> 添加节点
39
- add-component <文件> <节点路径> <类型> 给节点添加组件
40
- remove-component <文件> <节点路径> <类型> 删除节点组件
41
- remove <文件> <节点路径> 删除节点
42
- build <项目目录> 构建组件映射
43
- create-prefab [JSON文件路径] <输出.prefab> 创建预制体(不传JSON则创建默认)
44
- create-scene [JSON文件路径] <输出.fire> 创建场景(不传JSON则创建默认)
45
- screenshot <json文件> [选项] 渲染JSON并截图
46
-
47
- 节点路径格式:
48
- Canvas - 根节点下的 Canvas
49
- Canvas/MidNode - Canvas 下的 MidNode
50
- Canvas/GameScene/NodeA - 多层嵌套路径
51
-
52
- set 支持的节点属性:
53
- name 节点名称
54
- active 激活状态 (true/false)
55
- x X 坐标
56
- y Y 坐标
57
- width 宽度
58
- height 高度
59
- anchorX 锚点 X (0-1)
60
- anchorY 锚点 Y (0-1)
61
- opacity 透明度 (0-255)
62
- scaleX X 缩放
63
- scaleY Y 缩放
64
- rotation 旋转角度
65
-
66
- set-component 示例:
67
- cocos2d-cli set-component xxx.fire Canvas/Label Label string "Hello"
68
- cocos2d-cli set-component xxx.fire Canvas/Label Label fontSize 32
69
- cocos2d-cli set-component xxx.fire Canvas/Sprite Sprite sizeMode 0
70
-
71
- add 支持的选项:
72
- --x=<数值> 设置 X 坐标
73
- --y=<数值> 设置 Y 坐标
74
- --width=<数值> 设置宽度
75
- --height=<数值> 设置高度
76
- --scaleX=<数值> 设置 X 缩放
77
- --scaleY=<数值> 设置 Y 缩放
78
- --rotation=<角度> 设置旋转角度
79
- --active=true/false 设置激活状态
80
- --type=sprite/label/button 添加节点时指定组件类型
81
- --string=<文字> Label 文字内容 (配合 --type=label)
82
- --fontSize=<数值> Label 字体大小 (配合 --type=label)
83
-
84
- JSON 格式:
85
- 详见 SKILL.md 完整文档。简要示例:
86
- {
87
- "name": "Node",
88
- "width": 400, "height": 300,
89
- "x": 0, "y": 0,
90
- "anchorX": 0, "color": "#336699",
91
- "components": [
92
- { "type": "label", "string": "Hello", "horizontalAlign": "left" },
93
- { "type": "richText", "string": "<color=#3cb034>绿色</color>" }
94
- ],
95
- "children": [...]
96
- }
97
-
98
- 提示:配合 anchorX + horizontalAlign 实现靠左/靠右布局(见 SKILL.md)
99
-
100
- 示例:
101
- cocos2d-cli tree assets/main.fire
102
- cocos2d-cli get assets/main.fire Canvas/MidNode
103
- cocos2d-cli get assets/main.fire Canvas/MidNode x
104
- cocos2d-cli get assets/main.fire Canvas/MidNode Label
105
- cocos2d-cli set assets/main.fire Canvas/MidNode x 100
106
- cocos2d-cli set assets/main.fire Canvas/MidNode width 200
107
- cocos2d-cli set-component assets/main.fire Canvas/Label Label string "Hello World"
108
- cocos2d-cli add assets/main.fire Canvas NewSprite --type=sprite --x=100
109
- cocos2d-cli add-component assets/main.fire Canvas/MidNode label
110
- cocos2d-cli remove-component assets/main.fire Canvas/MidNode label
111
- cocos2d-cli remove assets/main.fire Canvas/MidNode
112
-
113
- # 从 JSON 文件创建场景
114
- cocos2d-cli create-scene scene.json assets/scene.fire
115
-
116
- # 从 JSON 文件创建预制体
117
- cocos2d-cli create-prefab panel.json assets/panel.prefab
118
-
119
- # 创建默认预制体(不传JSON)
120
- cocos2d-cli create-prefab assets/NewNode.prefab
121
-
122
- # 截图
123
- cocos2d-cli screenshot data.json
124
- cocos2d-cli screenshot data.json -o ./screenshots --width 1080 --height 1920
125
- `);
126
- }
127
-
128
- // 解析参数
129
- const args = process.argv.slice(2);
130
-
131
- if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
132
- showHelp();
133
- process.exit(0);
134
- }
135
-
136
- const commandName = args[0];
137
- const commandPath = commands[commandName];
138
-
139
- if (!commandPath) {
140
- console.error(`未知命令: ${commandName}`);
141
- console.error('运行 cocos2d-cli --help 查看可用命令');
142
- process.exit(1);
143
- }
144
-
145
- // 加载并执行命令
146
- try {
147
- const command = require(commandPath);
148
- command.run(args.slice(1));
149
- } catch (err) {
150
- console.error(`命令执行失败: ${err.message}`);
151
- process.exit(1);
152
- }