cocos2d-x通过zOrder来控制每个节点显示出来的顺序原理

       我们为了控制一个节点的显示层级关系,通常会用到设置zOrder来控制,那么,其中的原理又是怎样的呢?下面来探究一下。

       先上一段测试代码跟资源以及效果

#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"

USING_NS_CC;

using namespace cocostudio::timeline;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
	Size visibleSize = Director::getInstance()->getVisibleSize();
	Vec2 origin = Director::getInstance()->getVisibleOrigin();

	auto sp = Sprite::create("cocos-html5.png");
	sp->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
	this->addChild(sp, 0);
	auto sprite1 = Sprite::create("cocos2dbanner.png");
	sprite1->setPosition(Vec2(50,100));
	sp->addChild(sprite1, 2);
	auto sprite2 = Sprite::create("powered.png");
	sprite2->setPosition(Vec2(50,50));
	sp->addChild(sprite2, -2);
    return true;
}

  资源 

cocos2d-x通过zOrder来控制每个节点显示出来的顺序原理_第1张图片

 

 

 

效果

cocos2d-x通过zOrder来控制每个节点显示出来的顺序原理_第2张图片 

     我们首先创建一个精灵,然后向这个精灵中添加两个精灵,一个zorder是正的,一个是负的,可以发现正的显示在它的上面,负的显示在它的下面。为什么呢?

      来看看node的visit方法:

void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{
    // quick return if not visible. children won't be drawn.
    if (!_visible)
    {
        return;
    }

    uint32_t flags = processParentFlags(parentTransform, parentFlags);

    // IMPORTANT:
    // To ease the migration to v3.0, we still support the Mat4 stack,
    // but it is deprecated and your code should not rely on it
    _director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    _director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
    
    bool visibleByCamera = isVisitableByVisitingCamera();

    int i = 0;

    if(!_children.empty())
    {
        sortAllChildren();
        // draw children zOrder < 0
        for( ; i < _children.size(); i++ )
        {
            auto node = _children.at(i);

            if (node && node->_localZOrder < 0)
                node->visit(renderer, _modelViewTransform, flags);
            else
                break;
        }
        // self draw
        if (visibleByCamera)
            this->draw(renderer, _modelViewTransform, flags);

        for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
            (*it)->visit(renderer, _modelViewTransform, flags);
    }
    else if (visibleByCamera)
    {
        this->draw(renderer, _modelViewTransform, flags);
    }

    _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    
    // FIX ME: Why need to set _orderOfArrival to 0??
    // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
    // reset for next frame
    // _orderOfArrival = 0;
}

      这个方法中我们可以看到, 如果没有子节点的情况下只会把自己给渲染出来,如果有子节点,那么它会先根据其中的zOrder来从小到大排序,然后它先渲染小于0的子节点,再渲染它本身,最后渲染大于0的子节点,这个过程是递归的。由于后面渲染的是显示在前面渲染的上面,所以,我们就不难理解得出这个结论:

       一个节点的子节点,如果zorder是小于0,那么显示在这个节点的下面,否则显示在上面;由于是递归的,子节点的子节点的显示是相当于子节点而言的,并不影响这个节点。

 

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