Node类源代码不完全分析

本文分析了Node类在cocos2d-x中的核心特性,包括锚点的处理,如何进行变换矩阵计算,以及子节点的添加、排序和清理操作。此外,还介绍了Node的绘制流程,通过visit方法递归地渲染子节点,实现2D渲染的层次结构。
摘要由CSDN通过智能技术生成
1.锚点 
Vec2 _anchorPointInPoints;     ///< anchor point in points
Vec2 _anchorPoint;             ///< anchor point normalized (NOT in points)不描述点

const Vec2 & Node ::getAnchorPointInPoints() const
{
   
return _anchorPointInPoints ;
}

/// anchorPoint getter
const Vec2 & Node ::getAnchorPoint() const
{
   
return _anchorPoint ;
}
//各自获取两个变量

void Node ::setAnchorPoint( const Vec2 & point)
{
   
if (! point. equals ( _anchorPoint ))   
    {
        _anchorPoint = point;    
        _anchorPointInPoints.set(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y); 
        _transformUpdated = _transformDirty = _inverseDirty = true ;//用来标识是否进行矩阵计算
    }
}

// _anchorPointInPoints的值是Node点大小分别乘 _anchorPoint 在x,y轴上的分量所得到,可得知 _anchorPoint 是锚点比例而 _anchorPointInPoints 是具体点的坐标

//
// "cache" variables are allowed to be mutable
    mutable Mat4 _transform;      ///< transform 变换矩阵
    mutable bool _transformDirty;   ///< transform dirty flag 是否进行变换矩阵计算
    mutable Mat4 _inverse;        ///< inverse transform 倒转变换矩阵     
    mutable bool _inverseDirty;     ///< inverse transform dirty flag 是否进行..计算
    mutable Mat4 _additionalTransform; ///< transform 附加的变换矩阵
    bool _useAdditionalTransform;   ///< The flag to check whether the additional transform is dirty 使用附加变换矩阵
    bool _transformUpdated;         ///< Whether or not the Transform object was updated since the last frame  标识是否在场景更新的最后进行矩阵变换计算

2.addchild
Vector < Node *> _children;        ///< array of children nodes 用Vector来存放子节点
Node *_parent;                  ///< weak reference to parent node 

virtual  void   addChild( Node * child);
{
     this -> addChild (child, child-> _localZOrder , child-> _name );
}
virtual   void  addChild( Node * child, int localZOrder);
{
    this -> addChild (child, zOrder, child-> _name );
}
virtual  void   addChild( Node * child, int localZOrder, const std :: string &name);
{
    addChildHelper (child, localZOrder, INVALID_TAG , name, false );
}

virtual  void   addChild( Node * child, int localZOrder, int tag);
{    
    addChildHelper (child, localZOrder, tag, "" , true );
}
//最终调用addChildHelper
void  Node ::addChildHelper( Node * child, int localZOrder, int tag, const std :: string &name, bool setTag)
{
   
if ( _children . empty ())      //子节点列表为空则新建
    { 
        this->childrenAlloc();  // _children . reserve ( 4 );调用reserve方法申请空间
    }
   
    this->insertChild(child, localZOrder);

     if (setTag)
        child-> setTag (tag);
    else
        child->setName(name);//设置标签
   
    child->setParent(this);//设置当前节点为新加入节点的父节点
    child->setOrderOfArrival(s_globalOrderOfArrival++);//标记创建Node对象的总数
    // setOrderOfArrival(){ _orderOfArrival = orderOfArrival; }
    // int _orderOfArrival; ///< used to preserve sequence while sorting children with the same localZOrder    //看 nodeComparisonLess();                                            
}

//
void  Node ::insertChild( Node * child, int z)
{
    _transformUpdated = true;     //标识是否进行矩阵变换计算
    _reorderChildDirty = true ;    //标记是否重新排列子节点
    _children . pushBack (child);    //压进Vector中
    child-> _localZOrder = z;      
}

void  Node ::sortAllChildren()    //重新排列子节点
{
   
if ( _reorderChildDirty )
    {
        std :: sort ( std :: begin ( _children ), std :: end ( _children ), nodeComparisonLess );
       //使用迭代器,根据ZOrder排列子节点
        _reorderChildDirty = false
    }
}

bool nodeComparisonLess( Node * n1, Node * n2)
{
   
return ( n1-> getLocalZOrder () < n2-> getLocalZOrder () ||
           ( n1->
getLocalZOrder () == n2-> getLocalZOrder () && n1-> getOrderOfArrival () < n2-> getOrderOfArrival () )
           );
}
//

void Node ::reorderChild( Node *child, int zOrder)
{
    _reorderChildDirty = true ;
    child->setOrderOfArrival(s_globalOrderOfArrival++);
    child->_localZOrder = zOrder;//更新zOrder
}

void Node ::cleanup()
{
     // actions停止所有动作,并停止定时器调度
    this -> stopAllActions ();
   
this -> unscheduleAllCallbacks ();

    // timers遍历每个子节点调用cleanup()
    for ( const auto &child: _children )
        child->cleanup();
}

3,绘制Node
virtual void draw( Renderer *renderer, const Mat4 & transform, uint32_t flags);
virtual void draw() final;

virtual void visit( Renderer *renderer, const Mat4 & parentTransform, uint32_t parentFlags);
virtual void visit() final;

void Node ::visit( Renderer * renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{
    // quick return if not visible. children won't be drawn.不可见便返回
    if (! _visible )
    {
       
return ;
    }
    //矩阵变化
    _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);//递归visit子节点
            else
               
break ;
        }
       
// self draw
       
if (visibleByCamera)
            this->draw(renderer, _modelViewTransform, flags);
         // draw children zOrder > 0
        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 );

}

将Node显示到屏幕上使用Visit方法,在其中调用了draw来绘制node,visit方法遍历了二叉树,将所有子节点按照Zorder的顺序绘制出来
可重写draw()来让Node按自己方式绘制出来
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值