bug cocos2d-x 3.1 Node::sortAllChildren

先介绍一下,3.1版本 中 Node::sortAllChildren 的作用:

Node在绘制前,需要先将它的子节点(children)进行排序,然后按顺序地绘制出来,实现对应的层次关系。

一般而言,想要让一个node在父节点中显示得比较靠前,那就要把其zorder设置得较大一点,zorder大的会比zorder小的绘制得前,在3.1版本中,zorder改成了_localZOrder

然后有一种做法,假设有一个layer,上面有n个sprite,他们的zorder都一样,此时较后添加到layer的sprite,在绘制时会靠前,因为其排在了children队列后面。所以在都以相同的zorder添加到layer后,想要某个sprite显示在最前方,只要重新以相同的zorder来reorderChild就行了(相当于最后被添加到队列中)。

而sortAllChildren起的就是排序的作用,

在旧版本中,排序是遍历形势来比较换位的。

而3.1版本使用std::sort来进行排序,然而问题来了,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。这回影响什么呢?那么就要再说一个事,前面说过,主要绘制顺序会根据_localZOrder值来排序的。

但!!!当 _localZOrder 相同时,会判断另一个值,那就是 _orderOfArrival ,当调用reorderChild时,设置child的zorder同时也会设置orderOfArrival,这是个自增长的数,用来记录添加的子节点的顺序,就是说每加到父节点的子节点,其 _orderOfArrival 会被赋值,然后在sortAllChildren时,如果判断到 _localZOrder 相同,那么就会进行 _orderOfArrival 的判断,然后在一帧绘制完成后,因为children已经排序完毕,所以所有node的 _orderOfArrival 会被重新赋值为 0 。按照以前的版本,这样做是没问题的,但3.1版本使用快速排序,“多个相同的值的相对位置也许会在算法结束时产生变动”,所以当到了下一帧,所有节点的_orderOfArrival都会相同,而_localZOrder本来就是相同的,所以其排序后的位置顺序就会不稳定了,有时这个靠前,有时这个靠后,这就是所谓的bug了,我还发现,ios和android排序后的结果也不一样。

所以,大家要注意了,尽量不要把zorder设置成同一个值或者不设置,应该自己定好不同的zorder,这样才不会出现混乱。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值