最近在做一个塔防的项目,怎么说呢,炮台,子弹攻击特效加上受击特效等等等一顿代码撸下来一看dc稳定在200+,这还只是核心的游戏逻辑,如果加上ui那还得了,普通手机挂几分钟就直接挂掉,那就想只能先优化了,这个时候想到之前看过一个滑动层优化的代码,于是想着照葫芦画瓢直接把他的思想拿过来用啊,实践后发现果然可行,不得感叹大佬还是大佬。 先看看没有优化之前的dc,只有两种炮的情况下就是120了: 看看现在,n种炮加子弹特效加受击特效: 那就直接讲思路吧,首先在主场景中,挂一个节点,专门用来做渲染层的东西,比如这个项目中的炮,我就拧出来单独做一个节点存放,并挂上脚本turretRender.ts,它主要就是干两个事, 1.克隆一个需要用到的spine节点并加入到这个渲染节点下 2.不用的时候destroy掉 代码:
addRenderNodeToRoot(type,name:string, node:cc.Node){
let baseNode:cc.Node = this._turretRoot;
let parentNode:cc.Node = baseNode.getChildByName(name);
if(parentNode){
parentNode.addChild(node);
return;
}
parentNode = new cc.Node;
parentNode.name = name;
baseNode.addChild(parentNode);
parentNode.addChild(node);
}
removeSpineNodeFromRoot(node:cc.Node){
if(node){
node.destroy();
}
}
在我们加载spine的地方复制原节点,这个复制的节点就当做我们后面需要渲染的节点存在并把它加入到上面创建的turrtRender中,代码如下 : 加载spine动画的节点,加载完成后给他一个回调:
loadSpineImg(callback: Function) {
if (this.bulletSpine) {
this.bulletSpine.skeletonData = null;
}
this.loadSpine("spine/turret/" + this.bulletData.type + "/bullet/" + this.bulletData.name, sp.SkeletonData, (error, sp: sp.SkeletonData) => {
if (error) {
cc.warn(error);
return;
}
this.bulletSpine.skeletonData = sp;
callback && callback();
})
}
加载完成spine节点后的回调里处理克隆逻辑,在这里需要注意的是,我们要把原始节点隐藏,显示的是克隆出来的节点,位置设置好,后面对原始界面的操作全部改成克隆出来的节点操作,需要注意的是,记得判断克隆的节点是否存在的情况,还有要保证位置实时更新
this.loadSpineImg(() => {
if (this.cloneBulletSpine) {
turretRender.inst.removeSpineNodeFromRoot(this.cloneBulletSpine);
this.cloneBulletSpine = null;
}
this.cloneBulletSpine = cc.instantiate(this.bulletSpine.node);
this.cloneBulletSpine.removeAllChildren();
this.cloneBulletSpine.active = true;
this.bulletSpine.node.active = false;
let name: string = this.bulletData.type+"_paodan";
turretRender.inst.addRenderNodeToRoot(RenderNodeType.renderBulletSpine,name, this.cloneBulletSpine);
let wPos = this.bulletSpine.node.parent.convertToWorldSpaceAR(this.bulletSpine.node.getPosition());
let lPos = this.cloneBulletSpine.parent.convertToNodeSpaceAR(wPos);
this.cloneBulletSpine.setPosition(lPos);
//回调
if (this.bulletData.Spine == 1) {
this.cloneBulletSpine.getComponent(sp.Skeleton).setAnimation(0, this.bulletData.animationName, this.bulletData.loop == "1");
this.isMoment = false;
} else {
this.cloneBulletSpine.getComponent(sp.Skeleton).clearTracks();
this.playAni();
}
});
监听位置实时更新代码,要不然会出现位置偏移情况:
start() {
this.node.on(cc.Node.EventType.POSITION_CHANGED, this.updatePos, this);
this.bulletSpine.node.on(cc.Node.EventType.ROTATION_CHANGED, this.updatePos, this);
}
updatePos() {
if (this.bulletSpine && this.cloneBulletSpine) {
let wPos = this.bulletSpine.node.parent.convertToWorldSpaceAR(this.bulletSpine.node.getPosition());
let lPos = this.cloneBulletSpine.parent.convertToNodeSpaceAR(wPos);
this.cloneBulletSpine.setPosition(lPos);
this.cloneBulletSpine.angle = this.node.angle;
}
}
其实这样做主要的目的就是合批,如果是一个个的加上去,spine有些地方会打断合批操作,就导致合批不成功,dc就会相当高了。 ----------------------------------------------------------分割线---------------------------------------------------------------------- 推荐两个好用的插件: 1.查看dc的绘制情况:spector.js,自行百度怎么用吧,可以检测优化后dc绘制情况是否正确 如图,点击蓝色部分就是每次dc在绘制什么东西: 2.ccc-devtools插件,是可以看到整个cocos的层级结构,看看某个节点在哪个节点下,在这里可以监听克隆的spine节点是否加在了turretRender节点下
|