cocos2d-x 3.2渲染层级问题--层级突然变混乱

话说N年前,美女计算机老师讲排序的时候,快速排序方便简单实用,但是是不稳定的排序,所谓不稳定就是,通俗的来讲,排序数组里面有相等的值,排序后要与之前的次序保持不变.即numA = numB;排序前numA在numB前面,那么排序后numA也在numB前面,而不稳定的排序算法,numA可能会再numB的后面. 也许我没有讲清楚,简单理解就是"快速排序有个坑".

      不久前,第一次用cocos2d-x3.0开发项目,也就遇到了渲染层级问题。一些layer的层级从底层跑到上层了,比如背景图跑到最上面来了挡住了上面的UI,坑爹啊.

      小闫同学很快就找到了原因在node的zorder相同这一点上.因为在cocos2d-x 2.x的时候,这样写

      layerA->addchild(sprite1);

      layerA->addchild(sprite2);

     这样他们默认的层级虽然都是0,但是sprite2是在sprite1上面的.

      但是在3.0中这样写,他们的层级是处在未知变化中的,没错,未知变化.


这是因为在cocos2d-x,在visit一个node,会对它的所有child进行一次排序,基准是zorder的大小.

        在cocos2d-x2.x中是这样实现这个排序的:

void CCNode::sortAllChildren()
{
    if (m_bReorderChildDirty)
    {
        int i,j,length = m_pChildren->data->num;
        CCNode ** x = (CCNode**)m_pChildren->data->arr;
        CCNode *tempItem;

        // insertion sort
        for(i=1; i=0 && ( tempItem->m_nZOrder < x[j]->m_nZOrder || ( tempItem->m_nZOrder== x[j]->m_nZOrder && tempItem->m_uOrderOfArrival < x[j]->m_uOrderOfArrival ) ) )
            {
                x[j+1] = x[j];
                j = j-1;
            }
            x[j+1] = tempItem;
        }

        //don't need to check children recursively, that's done in visit of each child

        m_bReorderChildDirty = false;
    }
}
//很简洁的代码,对child进行了一个基于zoder的插入排序.(插入排序是稳定的排序算法)然而,在cocos2d-x 3.x中
void Node::sortAllChildren()
{
    if( _reorderChildDirty ) {
        std::sort( std::begin(_children), std::end(_children), nodeComparisonLess );
        _reorderChildDirty = false;
    }
}
bool nodeComparisonLess(Node* n1, Node* n2)
{
    return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
           ( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
           );
}
没错,代码除了写的精简点,没什么区别.唯一的区别是用了std::sort代替之前手写的插入排序,std::sort就是快速排序的封装.所以排完序之后就混乱了.其实可以嫌弃插入排序,但是这样让UI层级怎么愉快的玩耍.  不知道cocos2d-x团队有没有好的解决方案,难道是为了我们写更规范的代码?zorder规范管理:addchild(sprite1,1),addChild(sprite2,2)....

好吧,我也没想到好的解决方案,吐槽一下,no zuo no die ,why cocos2d-x3.x try?





你可能感兴趣的:(cocos2d-x)