编写兼容Creator 1.x和2.x的代码


640?wx_fmt=jpeg

有幸结识到社区中大名顶顶的Colin,Shawn在论坛上第一次看到Colin的团队用Cocos Creator开发的《热血暗黑》时就被深深地震撼到了!更为重要的是,Colin将他的技术心得和宝贵开发经验写成文字,每一篇分享都是满满的干活,而且幸运的是Shawn得到Colin的授权许可,将他的文章散播到奎特尔星球,与你一起欣赏一起成长!

引言

Creator 2.x出来有一段时间了,在原生应用上仍然不能让人满意,许多小伙伴花了大量精力把项目升级到2.x,结果发现性能内存大打折扣。

官方也意识这个问题,他们正组织核心人马,在对原生框架进行各种优化,包括Spine,Dragonbones,压缩纹理,文字优化等等,相信在不久的将来可以见到一些成效。

不过如果项目急着要上线,现在可能来不及了,并且优化的成果如何,也要实际放出来时测试过才能知道。在这种情况下,比较可行的方法是先用1.x发布你的应用,但在代码上作一些兼容性处理,确保到时升级时尽量平滑。甚至在最坏情况要回退,也少一些麻烦。

这篇文章试图将1.9和2.x的差异列举出来,并且告诉你如何写出在两个版本都可以运行的代码。1.10我们没有用过,使用1.10的小伙伴只能自行研究。

先定义版本常量

//如果是1.x的项目定义为true,如果是2.x的项目定义为false	
window.CC_1X  = true

ZOrder的差异

1.9可以用 node.setLocalZOrdernode.zIndex,2.x去掉了 setLocalZOrder函数,要兼容的话统一使用 node.zIndex

setCascadeOpacityEnabled废除

2.x去掉了 node.setCascadeOpacityEnabled,1.9要兼容的话就不能使用。另外cc.Node上还有多个API被废除,详见Creator API文档,链接:https://docs.cocos.com/creator/api/zh/。

播放声音的差异

  • 1.9的例子:

let sId = cc.audioEngine.play(	
    cc.url.raw("resources/sound/test.mp3")), 	
    loop, 	
    volume	
);
  • 2.x的例子:

cc.loader.loadRes("sound/test", cc.AudioClip, function (err, clip) {	
    if (err) {console.error(err); return;}	
    let sId = cc.audioEngine.play(clip, !!loop, volume);	
});
  • 兼容的做法是写一个包装函数:

playSound = function (name, loop, volume=1, cb) {	
    if (CC_1X) {	
        let sId = cc.audioEngine.play(	
            cc.url.raw("resources/sound/"+name+".mp3", 	
            !!loop, 	
            volume	
        );	
        if (cb) {	
            cb(sId);	
        }	
    } else {	
        cc.loader.loadRes("sound/"+name, cc.AudioClip, function (err, clip) {	
            if (err) { console.error(err); return;}	
            let sId = cc.audioEngine.play(clip, !!loop, volume);	
            if (cb) {	
                cb(sId);	
            }	
        });	
    }	
};

自定义事件的差异

  • 1.9的事件

// message 会被保存在回调函数的 event 参数的 detail 属性上	
eventTarget.emit(type, message); 	
eventTarget.on(type, function (event) {	
    // 通过 event.detail 获取message	
});
  • 2.x的事件

// emit 时可以传递至多五个额外参数,都会被扁平的直接传递给回调函数	
eventTarget.emit(type, message, target); 	
eventTarget.on(type, function (message, target) {	
    // 直接通过回调参数来获取 emit 时传递的事件参数	
});
  • 兼容的做法是确保参数只传一个,然后在事件处理是这样判断:

eventTarget.on(type, function (event) {	
    let msg = event.detail ? event.detail : event;	
    // 这样就能兼容1.9和2.x的事件机制	
});
  • 由于自定义事件的变化,导致按钮,动画组件等事件也有相应的变化,兼容的做法如下:

// 按钮的	
button.node.on("click", this.onClick, this);	
onClick(event) {	
    let button = event.detail ? event.detail : event;	
}	
// 动画的	
anim.on("finished", this.onFinished, this);	
onFinished(event, target) {	
    var aniState = target ? target : event.target;	
}

一些API的变化:

  • radiansToDegrees

if (CC_1X) {	
    return cc.radiansToDegrees(dirRad);	
} else {	
    return cc.misc.radiansToDegrees(dirRad);	
}
  • cc.KEY

if (CC_1X) {	
    cc.macro.KEY = cc.KEY;	
}
  • setKeepScreenOn

if (CC_1X) {	
    cc.Device.setKeepScreenOn(true);	
} else {	
    jsb.Device.setKeepScreenOn(true);	
}
  • 其他API不同,通过查询文档,然后用上面的方式写一个包装函数。

prefab的差异

我们当时将项目从2.0.5回退到1.9的时候,发现修改代码还不能成功,有些组件序列化格式的变化,导致用1.9打开会失败。

所以这里也将一些不兼容的地方列出来,方便有像我们一样想回退的小伙伴参考:

  • RichText:如果在2.0中设置了字符串,1.9打不开,解决办法是先在2.0编辑器中,将RichText的文本清空,1.9编辑器就可以正常打开了。

  • ScaleX和ScaleY属性如果不是1,回退到1.9会恢复成1。这也是因为格式不一致导致1.9没法解析出来。似乎没有好的办法,只能手动一个个修正过来。

  • EditBox 2.0多出几个子结点,要回到1.9只能手动删掉了,请看下图:640?wx_fmt=png

  • TTF字体:当字体文件体积大于10M时,2.0会加载失败,这应该属于引擎的BUG,期待后面修复。

meta文件的修改

  • .meta文件的版本号有变化,在2.x中有些是2.0.0的,如果想回退,可以用批处理替换回1.0.1。

其它差异

  • 2.x资源不存在直接报错,在运行时,1.x时资源不存在时只是做警告提示,2.x资源不存在直接报错。

  • 2.x构建资源全部以UUID命名:如果要在2.x上做热更新,需要建立Assets资源与构建资源的对应关系,相比1.x要复杂一些了。

  • rect.contains废弃使用cc.rectContainsPoint代替

640?wx_fmt=png

  • cc.pXXX系列函数被废弃,使用cc.Vec2成员函数 cc.pAdd需改为p.add,cc.pMult改为p.mul

640?wx_fmt=png

  • 两个点的距离计算cc.pDistance改为p1.sub(p2).mag()。

640?wx_fmt=png


如果公众号上的文章对你或你的朋友有所帮助,请记得分享给大家,愿我们一起成长!

640?wx_fmt=jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值