对CocosCreator3.x节点Node进行扩展,简化书写,提升性能。
演示Demo:https://gitee.com/szrpf/NodeEx
一、需求整理
相信很多从2.x转过来的同学对3.x的节点属性调整会比较别扭,例如:
2.x可以直接写:
this.node.x++;
this.node.width = 100;
this.node.anchorX = 1;
tween(this.node).to(1,{x:100,scaleX:3}).start();
3.x必须这么写:
this.node.setPosition(this.node.position.x+1,this.node.position.y);
let uiTrans = this.node.getComponent(UITransform);
uiTrans.width = 100;
uiTrans.anchorX = 1;
tween(this.node).to(1,{position:cc.v3(this.node.position.x+100,this.node.position.y)}).start();
tween(uiTrans).to(1,{width:100,anchor:cc.v2(1,uiTrans.anchorY)}).start();
二、构思方案
分析引擎源码,我猜官方是想合并事件消息才这么处理的
拿setPosition举例:
2.x
this.node.x = 3;this.node.y = 10;this.node.z = 0;
这样会emit3个位置变更事件
3.x
直接一句setPosition就设置3个坐标,只emit一个事件
但问题是,如果只设置x或y,那么setPosition也要象征性的把另一个捎带上,属实有点der~
优化思路
如果this.node.x只变更位置,不emit事件是不是就不存在以上问题了?
不但写起来省事,效率还更高(少了emit事件)
再扩展一下把2.x的scaleX、scaleY、width、height、anchorX,anchorY统统按照以上思路重写
那么UITransform的属性和node的属性可以在一个tween处理了
三、验证可行性
Object.defineProperties重定义属性
照抄引擎setPosition相关的源码,去掉emit事件发送的代码
发现".x"报错,说明底层并没有给Node设置x这个属性,运行一下看看。
节点确实移动了,符合预期。
至于报错问题,编写一个.d.ts文件声明一下就可以了。
至此,报错问题也顺利解决,而且在任何脚本里,节点对象按.都能出现x的语法提示
其余方法如法炮制,是不是2.x熟悉的感觉又回来了。
这里有2个坑:
1、扩展width、height、anchorX、anchorY的时候提示重定义
应该是引擎已经将这4个属性声明为废弃了
退而求其次,只能在后面加个后缀UT(代表UITransform)
希望官方能解除这个废弃声明
2、扩展color的时候,发现虽然直接node.color = cc.color(xxxx)有效
但是tween里面渐变color属性会闪,这是因为:
3.x的tween直接将color作为_val进行数值渐变,而非对r、g、b、a分别渐变
这个要重写tween来解决,不属于今天的讨论范围。
四、其他扩展函数
既然扩展了Node,顺便把以前写的节点函数也丢进来,分别是:
1、返回所有名称为name的子节点
findChildren(name: string, isStartWith: boolean = false): cc.Node[]
例如:this.node.findChildren(‘Title’); //返回所有名称为’Title’的子节点
this.node.findChildren(‘Tit’,true); //返回所有名称以’Tit’开头的子节点
2、在不改变世界坐标的前提下,设置锚点
setAnchor: (point: Vec2 | number, y?: number);
3、节点颜色time秒内渐变到color色值
setColor: (time: number, color?: Color);
例如:this.node.setColor(3,cc.color(255,0,0)); //节点颜色3秒内渐变到255,0,0
this.node.setColor(2); //节点颜色2秒内复原
注意:所有子节点也会跟着一起变色
4、节点震动repeat次,振幅amplitude,频率frequency
shake: (repeat: number, amplitude?: Vec3, frequency?: number);
例如:
this.node.shake(7,cc.v3(100,0,0),0.1); //节点振动7次,水平振幅100逐次递减,频率0.1秒
this.node.shake(-1,cc.v3(0,-50,0),0.5); //节点振动无限次,垂直振幅-50逐次递减,频率0.5秒
this.node.shake(0); //节点立即停止振动
5、实时销毁
this.node.destroyRealtime(); //销毁节点,并立即从层级树中移除
this.node.destroyChildrenRealtime(); //销毁所有子节点,并立即从层级树中移除子节点
五、结束语
NodeEx扩展的优势:
1、简化了书写
对于大量做项目的实战选手来说,这个很重要
2、提高了性能
大部分节点属性的emit事件是没必要的,NodeEx直接移除了emit,提高性能
如果需要监听事件,再用setPosition、setScale这些函数就行了
3、降低了2.x转型3.x的难度
很多代码都不用改了
演示Demo:https://gitee.com/szrpf/NodeEx
如何导入自己项目:
1、将Demo中NodeEx.ts复制到自己项目assets目录下
2、将Demo中NodeEx.d.ts复制到自己项目根目录下(与assets同级)
3、任意Node对象,按 . 就可以出现语法提示,可以像2.x一样调用
技术基本功决定下限
设计架构能力决定上限
不想面临35岁裁员危机
就多多锻炼框架设计能力吧
加油
Gitee地址:https://gitee.com/szrpf
EMail地址:27185709@qq.com
推荐链接:
1、【包教包会】CocosCreator3.x框架——资源管理(秒Loading、大厅子游戏、同步加载、极简对象池、多语言)
2、【包教包会】CocosCreator Assembler经典案例第一期——2D实现3D透视翻转(附Demo源码)
3、【包教包会】对CocosCreator富文本RichText进行全面优化