scene-accessor.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /*
  2. * @Author: CGT (caogtaa@gmail.com)
  3. * @Date: 2020-01-16 22:08:55
  4. * @Last Modified by: CGT (caogtaa@gmail.com)
  5. * @Last Modified time: 2020-01-16 22:08:55
  6. */
  7. const fs = require('fs');
  8. const path = require('path');
  9. function attachNode(node, parent, worldPos, callback) {
  10. // world position to relative position
  11. parent.addChild(node);
  12. node.position = parent.convertToNodeSpaceAR(worldPos);
  13. // todo: support undo
  14. if (callback) {
  15. callback(null, node);
  16. }
  17. }
  18. // load prefab by uuid, create instance under canvas or some parent node
  19. function insertNode(param, callback) {
  20. param = param || {worldX: 0, worldY: 0};
  21. let worldPos = cc.v2(param.worldX, param.worldY); // todo: uniform param
  22. let parent = null;
  23. if (param.parentId) {
  24. // @ts-ignore
  25. parent = cc.engine.getInstanceById(param.parentId);
  26. } else if (param.parent) {
  27. // @ts-ignore
  28. parent = param.parent
  29. } else {
  30. // canvas can be renamed, should find cc.Canvas component in scene top level
  31. // parent = cc.find('Canvas');
  32. let scene = cc.director.getScene();
  33. for (let s of scene.children) {
  34. if (s.getComponent(cc.Canvas)) {
  35. parent = s;
  36. break;
  37. }
  38. }
  39. }
  40. if (!parent) {
  41. if (callback)
  42. callback('Canvas or parent node not found, cancel.', null);
  43. return;
  44. }
  45. if (param.uuid) {
  46. cc.loader.load(
  47. {uuid: param.uuid, type: 'uuid'},
  48. null,
  49. function (error, prefab) {
  50. if (error) {
  51. Editor.log(error);
  52. if (callback) {
  53. callback(error, null);
  54. }
  55. return;
  56. }
  57. let node = cc.instantiate(prefab);
  58. attachNode(node, parent, worldPos, callback);
  59. }
  60. );
  61. } else {
  62. let node = new cc.Node();
  63. attachNode(node, parent, worldPos, callback);
  64. }
  65. }
  66. let gameType
  67. let semeID
  68. let gameID
  69. let partID
  70. let modeID
  71. let oldJson
  72. let wordCode
  73. let gameJson
  74. let typeArr = ['gameTest/', 'gameChild/', 'gameHome/', 'gameMath/', 'gamePass/', 'gameEndless/', 'gameChinese/', 'gameMathApp/', 'gamePoetry/', 'gamePinyin/']
  75. let typeSemeArr = ['gameTestSeme/', 'gameChildSeme/', 'gameHomeSeme/', 'gameMathSeme/', 'gamePassSeme/', 'gameEndlessSeme/', 'gameChineseSeme/', 'gameMathAppSeme/', 'gamePoetrySeme/', 'gamePinyinSeme/']
  76. function isEditor(event, param) {
  77. if (event && event.reply) {
  78. event.reply(null, 'Fine, thank you!');
  79. }
  80. semeID = param.semeID
  81. gameID = param.gameID
  82. partID = param.partID
  83. modeID = param.modeID
  84. gameType = param.gameType
  85. wordCode = param.word ? param.word.charCodeAt(0).toString() : ''
  86. param.wordCode = wordCode
  87. let scene = cc.director.getScene();
  88. let canvas
  89. let sceneName = scene.name
  90. for (let s of scene.children) {
  91. if (s.getComponent(cc.Canvas)) {
  92. canvas = s;
  93. break;
  94. }
  95. }
  96. if (sceneName != 'Editor' || !canvas) {
  97. event && event.reply('当前打开的场景不是Editor');
  98. }
  99. param.editorLog = (data) => {
  100. Editor.log(data)
  101. }
  102. return {canvas, param}
  103. }
  104. // @ts-ignore
  105. module.exports = {
  106. 'create-node': function (event, param) {
  107. let selected = Editor.Selection.curSelection('node');
  108. if (selected.length > 0) {
  109. param.parentId = selected[0];
  110. }
  111. insertNode(param, (error, node) => {
  112. if (node) {
  113. // select new node
  114. Editor.Selection.select('node', node.uuid);
  115. // Editor.log(`'${node.name}' created`);
  116. }
  117. if (event.reply) {
  118. event.reply(error);
  119. }
  120. });
  121. },
  122. 'importGame': function (event, config) {
  123. let {canvas, param} = isEditor(event, config)
  124. if (!canvas) return
  125. let editor = canvas.getComponent('Editor')
  126. let stageArr = [semeID, gameID, partID]
  127. if (modeID == '0') {
  128. gameJson = FileHelper.getObjectFromFile(path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  129. , addGameSGP('data_' + stageArr.join('_') + '.json', 3)))
  130. param.gameJson = gameJson
  131. }
  132. editor.clearNodes()
  133. let gamemode = ['', 'Drag', 'Select', 'Line', 'Maze', 'PageDrag', 'PageSelect', 'DrawImg', 'Show', 'PageShow',
  134. 'PageLine', 'Memory', 'EndlessSelect', 'Race', 'Couple', 'Hamster', 'WordMemory', 'PickUp']
  135. let prefabUrl = 'db://assets/prefab/gameMode/' + gamemode[modeID == '0' ? gameJson.gameMode : parseInt(modeID)] + 'UI.prefab'
  136. let uuid = Editor.assetdb.remote.urlToUuid(prefabUrl)
  137. Editor.Ipc.sendToPanel('scene', 'scene:create-nodes-by-uuids', [uuid], cc.find('game', canvas)['_id'], (err) => {
  138. // if (err) return
  139. if (modeID > 0) return
  140. editor.initGameByJson(param)
  141. let node = cc.find('game', canvas).children[0]
  142. let urlKey = 'db://assets/' + typeSemeArr[param.gameType]
  143. + addGameSGP('', 3)
  144. let bgUrlKey = 'db://assets/' + typeSemeArr[param.gameType]
  145. + addGameSGP('', semeID % 100 == 0 || param.gameType == 7 ? 3 : 2)
  146. this.setSpriteByName(cc.find('bg', node), bgUrlKey, gameJson.bg)
  147. if (param.gameType == 9) {
  148. let bgTex = 'editBg'
  149. if (gameID == 100) {
  150. bgTex = 'testBg'
  151. }
  152. if (semeID == 300) {
  153. bgTex = 'readBg'
  154. }
  155. this.setSpriteByName(cc.find('bg', node), 'db://assets/gamePinyin/texture/Public/', bgTex)
  156. } else {
  157. this.setSpriteByName(cc.find('bg', node), bgUrlKey, gameJson.bg)
  158. }
  159. this.setSpriteByName(cc.find('title', node), urlKey, gameJson.bt)
  160. if (gameJson.bgNode) {
  161. for (let i = 0; i < gameJson.bgNode.length; i++) {
  162. let bgNode = cc.find('bgNode', node)
  163. if (bgNode) this.setSpriteByName(bgNode.children[i], urlKey, gameJson.bgNode[i].tex)
  164. }
  165. }
  166. if ([5, 6, 9, 10].includes(gameJson.gameMode)) {
  167. let page1 = cc.find('page/view/content/page1', node)
  168. let page2 = cc.find('page/view/content/page2', node)
  169. let page1Data = gameJson.node.filter(value => value.page == 1)
  170. let page2Data = gameJson.node.filter(value => value.page == 2)
  171. for (let i = 0; i < page1Data.length; i++) {
  172. this.setSpriteByName(page1.children[i], urlKey, page1Data[i].tex)
  173. }
  174. for (let i = 0; i < page2Data.length; i++) {
  175. this.setSpriteByName(page2.children[i], urlKey, page2Data[i].tex)
  176. }
  177. } else {
  178. for (let i = 0; i < gameJson.node.length; i++) {
  179. let gameNode = cc.find('gameNode', node)
  180. if (gameNode) {
  181. let spriteNode = gameNode.children[i]
  182. if (gameJson.gameMode == 4) {
  183. spriteNode = cc.find('sprite', gameNode.children[i])
  184. }
  185. this.setSpriteByName(spriteNode, urlKey, gameJson.node[i].tex)
  186. }
  187. }
  188. }
  189. if (gameJson.answerNodes) {
  190. for (let i = 0; i < gameJson.answerNodes.length; i++) {
  191. let answerNode = cc.find('answer', node)
  192. if (answerNode) {
  193. for (let i = 0; i < answerNode.children.length; i++) {
  194. this.setSpriteByName(answerNode.children[i], urlKey, gameJson.answerNodes[i].tex)
  195. }
  196. }
  197. }
  198. }
  199. }, 1000)
  200. },
  201. 'outGameJson': function (event, config) {
  202. let {canvas, param} = isEditor(event, config)
  203. if (!canvas) return
  204. let editor = canvas.getComponent('Editor')
  205. param.oldJson = gameJson
  206. let outJson = editor.outGameJson(param)
  207. this.writeOutJson(outJson, event, param)
  208. },
  209. 'inBgAni': function (event, config) {
  210. let {canvas, param} = isEditor(event, config)
  211. if (!canvas) return
  212. let editor = canvas.getComponent('Editor')
  213. let yearID = semeID.substring(0, 2)
  214. let urlKey = 'db://assets/' + typeArr[param.gameType]
  215. + 'bgAni/' + yearID + '/'
  216. let getAniJonUrl = (ID) => {
  217. return path.join(Editor.Project.path, '/assets/' + typeArr[param.gameType]
  218. , 'bgAni', yearID, 'bgAni_' + ID + '_' + gameID + (param.gameType == 5 ? '_' + partID : '') + '.json')
  219. }
  220. let aniJson = FileHelper.getObjectFromFile(getAniJonUrl(yearID))
  221. if (Object.keys(aniJson).length == 0) {
  222. aniJson = FileHelper.getObjectFromFile(getAniJonUrl(semeID))
  223. }
  224. param.aniJson = aniJson
  225. editor.inBgAni(param)
  226. let bgNode = cc.find('game', canvas).children[0].getChildByName('bg')
  227. for (let key in aniJson) {
  228. let node = bgNode.getChildByName(key)
  229. let children = aniJson[key].children
  230. let initAniOrPar = (obj, node) => {
  231. if (obj.tex) this.setSpriteByName(node, urlKey, obj.tex)
  232. if (obj.ani) this.setAnimation(node, urlKey, obj.ani)
  233. if (obj.particle) this.setParticle(node, urlKey, obj.particle)
  234. }
  235. if (node) {
  236. initAniOrPar(aniJson[key], node)
  237. if (children) {
  238. for (let i = 0; i < children.length; i++) {
  239. initAniOrPar(children[i], node.children[i])
  240. }
  241. }
  242. }
  243. }
  244. },
  245. 'outBgAni': function (event, config) {
  246. let {canvas, param} = isEditor(event, config)
  247. if (!canvas) return
  248. let editor = canvas.getComponent('Editor')
  249. let outJson = editor.outBgAni(param)
  250. this.writeOutBgAniJson(outJson, event, param)
  251. },
  252. 'saveGameJson': function (event, config) {
  253. let {canvas, param} = isEditor(event, config)
  254. if (!canvas) return
  255. let src = Editor.Project.path.replace('\\', '\/') + '/assets/' + typeSemeArr[param.gameType] + addGameSGP('', 3)
  256. let dst = Editor.Project.path.replace('\\', '\/') + '/gameRes/' + typeSemeArr[param.gameType] + addGameSGP('', 3)
  257. FileHelper.copyDir(src, dst)
  258. event.reply(null, '关卡保存成功');
  259. Editor.log('关卡保存成功')
  260. },
  261. 'writeOutJson': function (outJson, event, param) {
  262. let stageArr = [semeID, gameID, partID]
  263. let savePath = 'db://assets/' + typeSemeArr[param.gameType]
  264. + addGameSGP('data_' + stageArr.join('_') + '.json', 3)
  265. if (outJson.gameMode == 7) {
  266. outJson.drawPos = FileHelper.getObjectFromFile(Editor
  267. .url('packages://cc-ext-scene-menu/' + typeArr[param.gameType] + 'DrawImg/' + stageArr.join('_') + '.json')
  268. )
  269. let errDrawPath = Editor
  270. .url('packages://cc-ext-scene-menu/' + typeArr[param.gameType] + 'DrawImg/' + stageArr.join('_') + '_e.json')
  271. if (fs.existsSync(errDrawPath)) {
  272. outJson.errDrawPos = FileHelper.getObjectFromFile(errDrawPath)
  273. }
  274. }
  275. fs.writeFileSync(path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  276. , addGameSGP('data_' + stageArr.join('_') + '.json', 3)), JSON.stringify(outJson, null, 2))
  277. if (!param.nofresh) {
  278. Editor.assetdb.refresh(savePath, (err, results) => {
  279. if (err) {
  280. event.reply('关卡导出失败');
  281. }
  282. event.reply(null, '关卡导出成功');
  283. })
  284. }
  285. },
  286. 'writeOutBgAniJson': function (outJson, event, param) {
  287. let yearID = semeID.substring(0, 2)
  288. let stageArr = [yearID, gameID]
  289. if (param.gameType == 5) {
  290. stageArr.push(partID)
  291. }
  292. if (param.gameType == 3 || param.gameType == 6) {
  293. stageArr[0] = semeID
  294. }
  295. let savePath = 'db://assets/' + typeArr[param.gameType] + 'bgAni/'
  296. + yearID + '/bgAni_' + stageArr.join('_') + '.json'
  297. fs.writeFileSync(path.join(Editor.Project.path, '/assets/' + typeArr[param.gameType] + 'bgAni/'
  298. , yearID, '/bgAni_' + stageArr.join('_') + '.json'), JSON.stringify(outJson, null, 2))
  299. Editor.assetdb.refresh(savePath, (err, results) => {
  300. if (err) {
  301. event.reply('导出背景动画失败');
  302. }
  303. event.reply(null, '导出导出背景动画成功');
  304. })
  305. },
  306. 'guideImport': function (event, config) {
  307. let {canvas, param} = isEditor(event, config)
  308. if (!canvas) return
  309. let editor = canvas.getComponent('Editor')
  310. editor.clearNodes()
  311. let stageArr = [semeID, gameID]
  312. let urlLevel = 2
  313. let guideUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  314. , addGameSGP('guide/guide_' + stageArr.join('_') + '.json', urlLevel))
  315. if (param.gameType == 6) {
  316. guideUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  317. , wordCode, 'guide/guide_' + wordCode + '.json')
  318. }
  319. gameJson = FileHelper.getObjectFromFile(guideUrl)
  320. param.gameJson = gameJson
  321. let prefabUrl = 'db://assets/prefab/public/GuideUI.prefab'
  322. if (param.gameType == 6) {
  323. prefabUrl = 'db://assets/prefab/chinese/ChineseMainUI.prefab'
  324. }
  325. let uuid = Editor.assetdb.remote.urlToUuid(prefabUrl)
  326. Editor.Ipc.sendToPanel('scene', 'scene:create-nodes-by-uuids', [uuid], cc.find('game', canvas)['_id'], (err) => {
  327. // if (Object.keys(gameJson).length > 0) {
  328. editor.importGuide(param)
  329. let node = cc.find('game', canvas).children[0]
  330. if (param.gameType == 7) {
  331. let bgUrlKey = 'db://assets/' + typeSemeArr[param.gameType]
  332. + addGameSGP('', 2) + 'guide/'
  333. this.setSpriteByName(cc.find('bg', node), bgUrlKey, 'bg')
  334. }
  335. // }
  336. }, 1000)
  337. },
  338. 'guideOut': function (event, config) {
  339. let {canvas, param} = isEditor(event, config)
  340. if (!canvas) return
  341. let editor = canvas.getComponent('Editor')
  342. let outJson = editor.outGuideJson(param)
  343. let stageArr = [semeID, gameID]
  344. let urlLevel = 2
  345. let jsonUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  346. , addGameSGP('guide/guide_' + stageArr.join('_') + '.json', urlLevel))
  347. let savePath = 'db://assets/' + typeSemeArr[param.gameType]
  348. + addGameSGP('guide/guide_' + stageArr.join('_') + '.json', urlLevel)
  349. if (param.gameType == 6) {
  350. jsonUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  351. , wordCode, '/guide/guide_' + wordCode + '.json')
  352. savePath = 'db://assets/' + typeSemeArr[param.gameType]
  353. + wordCode + '/'
  354. }
  355. FileHelper.mkDirsSync(path.dirname(jsonUrl))
  356. fs.writeFileSync(jsonUrl, JSON.stringify(outJson, null, 2))
  357. Editor.assetdb.refresh(savePath, (err, results) => {
  358. if (err) {
  359. event.reply('引导文件导出失败');
  360. }
  361. event.reply(null, '引导文件导出成功');
  362. })
  363. },
  364. 'savaGuide': function (event, config) {
  365. let {canvas, param} = isEditor(event, config)
  366. if (!canvas) return
  367. let urlLevel = 2
  368. if (param.gameType == 6) {
  369. urlLevel = 3
  370. }
  371. let assetsStartUrl = Editor.Project.path.replace('\\', '\/') + '/assets/' + typeSemeArr[param.gameType]
  372. let gameResStartUrl = Editor.Project.path.replace('\\', '\/') + '/gameRes/' + typeSemeArr[param.gameType]
  373. let getSrc = (key, level = 0) => {
  374. if (!level) level = urlLevel
  375. let src = assetsStartUrl + addGameSGP(key, level)
  376. return src
  377. }
  378. let getDst = (key, level = 0) => {
  379. if (!level) level = urlLevel
  380. let dst = gameResStartUrl + addGameSGP(key, level)
  381. return dst
  382. }
  383. if (param.gameType == 6) {
  384. FileHelper.copyDir(assetsStartUrl + wordCode + '/', gameResStartUrl + wordCode + '/')
  385. FileHelper.copyFile(assetsStartUrl + wordCode + '.meta', gameResStartUrl + wordCode + '.meta')
  386. } else {
  387. FileHelper.copyDir(getSrc('guide/'), getDst('guide/'))
  388. FileHelper.copyFile(getSrc('guide.meta'), getDst('guide.meta'))
  389. }
  390. event.reply(null, '引导文件保存成功');
  391. Editor.log('引导文件保存成功')
  392. },
  393. 'playGuide': function (event, config) {
  394. let {canvas, param} = isEditor(event, config)
  395. if (!canvas) return
  396. let editor = canvas.getComponent('Editor')
  397. editor.playGuide()
  398. },
  399. 'playNodeGuide': function (event, config) {
  400. let {canvas, param} = isEditor(event, config)
  401. if (!canvas) return
  402. let editor = canvas.getComponent('Editor')
  403. editor.playNodeGuide()
  404. },
  405. 'pauseGuide': function (event, config) {
  406. let {canvas, param} = isEditor(event, config)
  407. if (!canvas) return
  408. let editor = canvas.getComponent('Editor')
  409. editor.pauseGuide()
  410. },
  411. 'resetGuide': function (event, config) {
  412. let {canvas, param} = isEditor(event, config)
  413. if (!canvas) return
  414. let editor = canvas.getComponent('Editor')
  415. editor.resetGuide()
  416. },
  417. 'guidePageChange': function (event, config) {
  418. let {canvas, param} = isEditor(event, config)
  419. if (!canvas) return
  420. let editor = canvas.getComponent('Editor')
  421. editor.guideChangePage(param.guidePage)
  422. },
  423. 'teacherImport': function (event, config) {
  424. let {canvas, param} = isEditor(event, config)
  425. if (!canvas) return
  426. let editor = canvas.getComponent('Editor')
  427. editor.clearNodes()
  428. let stageArr = [semeID, gameID]
  429. let urlLevel = 2
  430. let teacherUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  431. , addGameSGP('teacher/teacher_' + stageArr.join('_') + '.json', urlLevel))
  432. gameJson = FileHelper.getObjectFromFile(teacherUrl)
  433. param.gameJson = gameJson
  434. let prefabUrl = 'db://assets/prefab/public/TeacherGuideUI.prefab'
  435. let uuid = Editor.assetdb.remote.urlToUuid(prefabUrl)
  436. Editor.Ipc.sendToPanel('scene', 'scene:create-nodes-by-uuids', [uuid], cc.find('game', canvas)['_id'], (err) => {
  437. // if (Object.keys(gameJson).length > 0) {
  438. editor.importTeacher(param)
  439. let node = cc.find('game', canvas).children[0]
  440. let urlKey = 'db://assets/' + typeSemeArr[param.gameType]
  441. + addGameSGP('', urlLevel) + '/teacher/'
  442. if (gameJson.bgNode) {
  443. for (let i = 0; i < gameJson.bgNode.length; i++) {
  444. let bgNode = cc.find('bgNode', node)
  445. if (bgNode) this.setSpriteByName(bgNode.children[i], urlKey, gameJson.bgNode[i].tex)
  446. }
  447. }
  448. for (let i = 0; i < gameJson.node.length; i++) {
  449. let gameNode = cc.find('gameNode', node)
  450. if (gameNode) {
  451. let spriteNode = gameNode.children[i]
  452. this.setSpriteByName(spriteNode, urlKey, gameJson.node[i].tex)
  453. }
  454. }
  455. // }
  456. }, 1000)
  457. },
  458. 'teacherOut': function (event, config) {
  459. let {canvas, param} = isEditor(event, config)
  460. if (!canvas) return
  461. let editor = canvas.getComponent('Editor')
  462. let outJson = editor.outTeacherJson(param)
  463. let stageArr = [semeID, gameID]
  464. let urlLevel = 2
  465. let jsonUrl = path.join(Editor.Project.path, '/assets/' + typeSemeArr[param.gameType]
  466. , addGameSGP('teacher/teacher_' + stageArr.join('_') + '.json', urlLevel))
  467. let savePath = 'db://assets/' + typeSemeArr[param.gameType]
  468. + addGameSGP('teacher/teacher_' + stageArr.join('_') + '.json', urlLevel)
  469. FileHelper.mkDirsSync(path.dirname(jsonUrl))
  470. fs.writeFileSync(jsonUrl, JSON.stringify(outJson, null, 2))
  471. Editor.assetdb.refresh(savePath, (err, results) => {
  472. if (err) {
  473. event.reply('讲解文件导出失败');
  474. }
  475. event.reply(null, '讲解文件导出成功');
  476. })
  477. },
  478. 'savaTeacher': function (event, config) {
  479. let {canvas, param} = isEditor(event, config)
  480. if (!canvas) return
  481. let urlLevel = 2
  482. let assetsStartUrl = Editor.Project.path.replace('\\', '\/') + '/assets/' + typeSemeArr[param.gameType]
  483. let gameResStartUrl = Editor.Project.path.replace('\\', '\/') + '/gameRes/' + typeSemeArr[param.gameType]
  484. let getSrc = (key, level = 0) => {
  485. if (!level) level = urlLevel
  486. let src = assetsStartUrl + addGameSGP(key, level)
  487. return src
  488. }
  489. let getDst = (key, level = 0) => {
  490. if (!level) level = urlLevel
  491. let dst = gameResStartUrl + addGameSGP(key, level)
  492. return dst
  493. }
  494. FileHelper.copyDir(getSrc('teacher/'), getDst('teacher/'))
  495. FileHelper.copyFile(getSrc('teacher.meta'), getDst('teacher.meta'))
  496. event.reply(null, '讲解文件保存成功');
  497. Editor.log('讲解文件保存成功')
  498. },
  499. 'setSpriteByName': function (node, urlKey, tex) {
  500. if (node && tex) {
  501. let uuid = Editor.assetdb.remote.urlToUuid(urlKey + tex + '.png/' + tex)
  502. if (uuid) {
  503. let data = {
  504. id: node.getComponent(cc.Sprite).uuid,
  505. path: "spriteFrame",//要修改的属性
  506. type: "cc.SpriteFrame",
  507. value: {uuid: uuid},
  508. isSubProp: false,
  509. }
  510. Editor.Ipc.sendToPanel('scene', 'scene:set-property', data);
  511. return true
  512. }
  513. }
  514. return true
  515. },
  516. 'setAnimation': function (node, urlKey, ani) {
  517. if (node && ani) {
  518. let uuid = Editor.assetdb.remote.urlToUuid(urlKey + ani + '.anim')
  519. if (uuid) {
  520. let data = {
  521. id: node.getComponent(cc.Animation).uuid,
  522. path: "defaultClip",//要修改的属性
  523. type: "cc.AnimationClip",
  524. value: {uuid: uuid},
  525. isSubProp: false,
  526. }
  527. Editor.Ipc.sendToPanel('scene', 'scene:set-property', data);
  528. return true
  529. }
  530. }
  531. return true
  532. },
  533. 'setParticle': function (node, urlKey, particle) {
  534. if (node && particle) {
  535. let uuid = Editor.assetdb.remote.urlToUuid(urlKey + particle + '.plist')
  536. if (uuid) {
  537. let data = {
  538. id: node.getComponent(cc.ParticleSystem).uuid,
  539. path: "file",//要修改的属性
  540. type: "cc.ParticleAsset",
  541. value: {uuid: uuid},
  542. isSubProp: false,
  543. }
  544. Editor.Ipc.sendToPanel('scene', 'scene:set-property', data);
  545. return true
  546. }
  547. }
  548. return true
  549. }
  550. }
  551. function addPreZero(num, length) {
  552. let numstr = num.toString()
  553. const l = numstr.length
  554. if (numstr.length >= length) {
  555. return numstr
  556. }
  557. for (let i = 0; i < length - l; i++) {
  558. numstr = `0${numstr}`
  559. }
  560. return numstr
  561. }
  562. function addGameSGP(data, level = 3) {
  563. let url = ''
  564. if (level >= 1) {
  565. url = url + 'S' + semeID + '/' // 是否包含S(课程)
  566. }
  567. if (level >= 2) {
  568. if (gameID) {
  569. url = url + 'G' + Math.addPreZero(gameID, 2) + '/' // 是否包含G(游戏)
  570. }
  571. }
  572. if (level >= 3) {
  573. if (partID) {
  574. url = url + 'P' + Math.addPreZero(partID, 2) + '/' // 是否包含P(关卡)
  575. }
  576. }
  577. return url + data
  578. }
  579. let FileHelper = {
  580. // 输出到文件
  581. writeFile(fullPath, content) {
  582. if (!fullPath || !content) {
  583. Editor.error('writeFile: invalid params');
  584. return;
  585. }
  586. fs.writeFile(fullPath, content, (err) => {
  587. if (err) {
  588. Editor.error(err);
  589. return;
  590. }
  591. Editor.log('Success to write file: ' + fullPath);
  592. });
  593. },
  594. // 返回文件内容的json对象
  595. getObjectFromFile(fullPath) {
  596. let retObj = {};
  597. if (!fs.existsSync(fullPath)) {
  598. Editor.warn('getObjectFromFile: NoExist path=' + fullPath);
  599. return retObj;
  600. }
  601. let str = this.getFileString(fullPath);
  602. if (!str) {
  603. Editor.warn('getObjectFromFile: invalid file=' + fullPath);
  604. return retObj;
  605. }
  606. retObj = JSON.parse(str);
  607. if (!retObj) {
  608. Editor.warn('getObjectFromFile: invalid object=' + fullPath);
  609. return retObj;
  610. }
  611. return retObj;
  612. },
  613. // 返回文件内容的字符串形式
  614. getFileString(fullPath) {
  615. if (fs.existsSync(fullPath)) {
  616. return fs.readFileSync(fullPath).toString();
  617. } else {
  618. return undefined
  619. }
  620. },
  621. copyFile(src, dst) {
  622. fs.writeFileSync(dst, fs.readFileSync(src))
  623. },
  624. mkDirsSync(dirname) {
  625. if (fs.existsSync(dirname)) {
  626. return true;
  627. } else if (this.mkDirsSync(path.dirname(dirname))) {
  628. fs.mkdirSync(dirname);
  629. return true;
  630. }
  631. return false;
  632. },
  633. delDir(dirPath) {
  634. let files = [];
  635. if (fs.existsSync(dirPath)) {
  636. files = fs.readdirSync(dirPath);
  637. files.forEach((file) => {
  638. const curPath = path.join(dirPath, file);
  639. if (fs.statSync(curPath).isDirectory()) {
  640. this.delDir(curPath); // 递归删除文件夹
  641. } else {
  642. fs.unlinkSync(curPath); // 删除文件
  643. }
  644. });
  645. fs.rmdirSync(dirPath);
  646. }
  647. },
  648. copyDir(srcPath, dstPath) {
  649. this.delDir(dstPath)
  650. this.mkDirsSync(dstPath)
  651. let files = fs.readdirSync(srcPath)
  652. if (files) {
  653. files.forEach((file) => {
  654. if (fs.statSync(srcPath + file).isDirectory()) {
  655. this.copyDir(srcPath + file + '/', dstPath + file + '/')
  656. } else {
  657. this.copyFile(srcPath + file, dstPath + file)
  658. }
  659. })
  660. }
  661. }
  662. };