急急!一句代码增加了40多个drawcall

   self.ani_state_.m_pCharSprite.zIndex = (1024 - (self.ani_state_.m_pCharSprite.getPositionY()));//1-2
       如果每帧都执行这一句,帧数下降1/2啊!

就这样更改一下zindex ,小游戏实测多了40多个drawcall,
m_pCharSprite 大约有十几个cc.animation,这应该算一个bug吧?

提供下demo,我们排查一下!

大神,我层层筛选,发现问题是在spriteframe这。交代一下问题,折腾了一整天了。
游戏逻辑是创建出墙来,然后根据墙的连续情况重置墙的spriteframe。

替换图片的代码是
mainGameView.SharedMainView.m_tmxMap.removeChild(self.sprite_, true); //场景移除
// this.sprite_.getComponent(cc.Sprite).spriteFrame.getTexture().destroy();

    this.sprite_.destroy(); //destroy
    this.sprite_ = null;
    this.sprite_ = new cc.Node();
    this.sprite_.setScale(0.5);
    //重新创建了this.sprite_,然后添加到了场景中
    var sp = this.sprite_.addComponent(cc.Sprite);
    sp.trim = false;
    sp.sizeMode = cc.Sprite.SizeMode.RAW;
   
    mainGameView.SharedMainView.m_tmxMap.addChild(this.sprite_);

//看这里,这里重新loadres 加载新的图片给 sprite_
gameData.loadImage(pszFileName,function (png) {
sp.spriteFrame = png;
});

如此替换后drawcall在160左右(墙有200多个)
神奇的地方来了!这样直接替换后,drawcall的数量是对的,但如果这时候在update里添加上这么一句
self.sprite_.zIndex = (1024 - (self.sprite_.getPositionY())); //根据Y轴设置Zindex

好了,drawcall会直接到310多,我怀疑是不是之前的spriteframe没释放,各种尝试释放,也没有找到想要的释放方式,比如我尝试的这句// this.sprite_.getComponent(cc.Sprite).spriteFrame.getTexture().destroy(); node会直接成黑,大神给指点一下啊,搞了一两天了

// var spriteFrame = self.sprite_.getComponent(cc.Sprite).spriteFrame;
// var deps = cc.loader.getDependsRecursively(spriteFrame);
// cc.loader.release(deps);

也尝试了这种释放,drawcall还是310?为什么会出现这样的情况

你改动了连续绘制中间的顺序,还是update里面,所有的都需要重绘, drawcall无法合并很正常吧

这得看你 具体的美术表现,用取巧的方式来更换图层顺序, update里改zIndex是很糟糕的方式

感谢您的回复,其实是帧计数30次一刷新,刷新之后drawcall就一直居高不下

而且有移动判断,当目标有移动的时候才会刷新zindex,墙并没有持续的刷新zindex,就初始化的时候执行一次

因为写的代码很多,我还很难抽出一个demo来,愁

你看node的源码,一旦调用 zIndex setter,zIndex如果和旧的值不等,会触发 parent.sortAllChildren, 会导致整个 parent 在下一帧被重绘

zIndex并不推荐是一个随意设置的值,而是表示了他在 parent.children 数组中的 index
(我认为你写的这个就是随意设置的值 (1024 - (self.sprite_.getPositionY())) )

而很多时候,人物走了几个像素,不到半个 tile时,并不会应该发生层级变化

你这只是达到了显示上的效果,但是是最差的实现方式

感谢。但现在是,如果替换图片的方法中的(这个方法是我自己封装了loadres)
gameData.loadImage(pszFileName,function (png) {
sp.spriteFrame = png;
});
注释掉,zindex就不会出现这个问题,出现drawcall暴涨的情况就是在给 墙替换了图片之后

(1024 - (self.sprite_.getPositionY())) ) 这一句的作用是根据移动角色的位置设置Z轴,人物的移动是我自己做的,没有使用runaction这样的方法,是自己每帧计算,人物的移动速度大约rate30的时候一秒走半个tile,所以就写了【如果角色在移动,且update累计超过30则更新一次zindex】

为什么要1024去减 是因为还有其他的建筑,自己想了个办法来排序Z轴

现在的问题就是:生成了200个墙,然后设置一个默认的图片,然后根据墙的依靠关系,更改图片,更改前 zindex 刷新并不会出现暴涨。但如果更改后,zindex就会暴涨。

墙的z轴只在初始化了之后更改过一次,并未持续刷新Z,更改图片后、刷新了一次之后,drawcall暴涨

我个人感觉页面创建的时候把墙初始化一下默认图片,再根据位置刷新一下图片,然后排序一下墙的zindex,不应该出现这种暴涨啊

这个是墙更改之后,drawcall310

墙未替换图片之前,这个时候就算每帧都刷zindex,也不会暴涨drawcall

墙是单独的 png, 不在同一个 sprite sheet 里面??

我是开发到微信小程序,只有在发布的时候才有自动图集,但在小游戏上测,也是出现了替换后暴涨,帧数下降

你加载墙的不是应该是类似

node.getComponent(‘cc.Sprite’).spriteFrame = atlas.getSpriteFrame(XXXX);

不应该是 img 吧

自动图集只能用于默认拖上去的。 你这种动态的,得用 texturePacker自己打包图集

1赞

可能是最近两个星期一直做优化做迷糊了,小程序上因为有自动图集,替换了墙之后drawcall未暴涨,确认为自动图集的问题。谢楼上