cocos2dx-lua项目迁移到Cocos Creator¶
目前在工作中遇到一些比较老的项目想要发布到H5平台,所以就出现了从cocos2dx-lua项目迁移到Cocos Creator的需求 这里将讲述用得到的一些步骤和需要注意的问题
step1 Lua转换为TypeScript¶
在nodejs中有一个模块叫lua-to-typescript,安装之后通过这个模块来转换
然后使用ltts命令行来转换
ltts main.lua
#生成main.ts,后面的参数是需要转换的文件路径
ltts a.lua b.lua c.lua ...
#生成 a.ts, b.ts, c.ts, ...
ltts -d library.lua
# 生成 library.d.ts
如果希望直接转换整个目录的话,你可以使用bat,当然你需要在相应的目录中执行
PS:执行脚本过程中可能遇到的问题,目前不支持do end语法(好像还有其他的,但是我忘记了,回头补充)
step2 ccbi转化为Prefab¶
这个请参考之前的文章ccbi转换为ccb
step3 代码部分的修补¶
- lua中的数组下标从1开始,而ts是从0开始,所以需要注意
-
使用脚本转换后,目前我观察到的elseif语句的条件和结果都会出问题,具体表现是
可以看到明显的错误,这部分也需要自己单独处理 -
静态函数或者说方法可能需要单独处理
-
this的指向问题 很多时候函数的转换会是这样
在lua中这没有问题,但是到ts中this的指向这个时候变成了Window,所以count是取不到的,需要修改为```ts class a{ count = 1; test(){ let foo = ()=> { this.count = this.count + 1; } foo(); } } - 部分for循环
ipairs这个关键字也不能被正常转换,需要修正为 - lua中table到ts后的实际类型 在ts中table更像是ts中的objcet,没有明确的结构,在转换时可能出现下面2种情况
- 正常转化为数组 - 转化为object 在第1种转换后你可以用之前提到的for循环处理,但是第二种就不行了 你需要使用如下代码来循环for (const k in array) { if (Object.prototype.hasOwnProperty.call(array, k)) { let v = array[k]; } }
step4 prefab的修补¶
- 图片尺寸异常 ccbi转换到prefab后可能因为版本的部分,采用SLICED模式的图片尺寸会丢失,这个时候只能挨个查看修改
- 互相引用的ccbi文件丢失 比如在A.ccbi中包含了B.ccbi,那转换到prefab后可能就不会显示B了,而且也不知道引用了B,只知道引用了一个ccbFile,这个也只能是你根据原版来查看判断引用的是哪个
- 字号异常 当使用自制的字体时通常会出现这个问题,也只能自己按个找到引用然后修改了
- Button组件的修改 在转换过程中通常Button会挂载4张图片,供4个状态使用,但是转换过来的prefab中并没有指定带有sprite组件的target所以并不能顺利的达到想要的效果,只能手动给Button组件指定target
step5 针对Cocos2dx-Lua特有的一些问题¶
- TableView的转化
在cococs creator中并没有专门的TableView,通常我使用ScrollView来替代,比如转换后function Test:reloadListView() local boardWidth = self._rootnode.listView:getContentSize().width local boardHeight = self._rootnode.listView:getContentSize().height local function createFunc(index) local item = require("Item").new() return item:create({ viewSize = cc.size(boardWidth, boardHeight), itemData = self._listData[index + 1], openFunc = function(cell) local idx = cell:getIdx() + 1 local itemData = self._listData[idx] foo(itemData) end }) end local function refreshFunc(cell, index) cell:refresh(self._listData[index + 1]) end local cellContentSize = require("Item").new():getContentSize() self._listViewTable = require("utility.TableViewExt").new({ size = cc.size(boardWidth, boardHeight), direction = kCCScrollViewDirectionVertical, createFunc = createFunc, refreshFunc = refreshFunc, cellNum = #self._listData, cellSize = cellContentSize }) self._listViewTable:setPosition(0, 0) self._rootnode.listView:addChild(self._listViewTable) end
这样转化之后基本上能和之前的TableView保持一致,唯一可能存在的问题是当列表数据太多时,性能上会有影响class test{ listView: cc.ScrollView; _listData: any[]; reloadListView(){ let length = Math.max(this.listView.content.length, this._listData.length); for (let index = 0; index < length; index++) { const data = this._listData[index]; let node = this.listView.content.children[index]; if (data) { if (!node) { let item = await Item.createNode(); item.init({ index: index, itemData: data, openFunc: (cell: GuildFuliItem) => { let itemData = cell.itemData; foo(itemData); } }); this.listView.content.addChild(item.node); } else { let item = node.getComponent(GuildFuliItem); item.refresh({ index: index, itemData: data }); } } else if (node) { node.active = false; } } } } const { ccclass, property } = cc._decorator; @ccclass class Item extends cc.Component { itemData; openFunc; static async createNode() { //ResMgr.loadPrefab的具体实现没有在这里写明,就是加载Prefab let node = cc.instantiate(await ResMgr.loadPrefab("item")); return node.addComponent(Item); } init(param: { itemData, openFunc: Function, }) { this.openFunc = param.openFunc; this.refreshItem(param); } refresh(param: { itemData, }) { this.refreshItem(param); } refreshItem(param: { itemData: GuildFuliData }) { this.itemData = param.itemData; //具体实现不写了 } }
- 添加Button和Sprite等组件时的差异 在cocos2dx中基本上Button等都是节点的子类,但是到了cocos creator中就变成了组件,都需要单独挂载在一个节点上,所以一定要弄清楚要操作的是节点还是组件
写在最后¶
本文是本人在最近转换项目时所遇到的真实案例,可能还有一些地方忘记了,后续补充,有疑问可以页面右下角邮件我,不定期回复.