cocos2d-x - Node 节点

本文围绕Cocos2d的Node节点展开,介绍了其常用子类、属性及操作,如添加子节点、使用定时器等。阐述了节点的生命周期,包括初始化、进入、退出等阶段的调用方法。还说明了设置场景、通知节点的流程,以及三种层级标记渲染顺序的规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Node

Node常用子类包括Scene, Layer, Widget等,常用属性有旋转(float _rotationX, float _rotationY)、伸缩(float _scaleX, float _scaleY)、位置(Vec2 _position)、倾斜(float _skewX, float _skewY)、锚点(Vec2 _anchorPoint)、大小(Size _contentSize)、全局层级(float _globalZOrder)和可见性(bool _visible)等,支持添加子节点(addChild, removeChild),使用定时器(schedule, unschedule),执行动画(runAction, stopAction)等操作。

  • 生命周期:

    子类重写以下方法时必须显示调用父类对应的方法。

    • init():初始化节点时调用。
    • onEnter():进入节点时调用。
    • onEnterTransitionDidFinish():进入节点而且过渡动画结束时候调用。
    • update(float delta):如果想要每帧执行Update方法,必须先调用scheduleUpdate方法。只重写Update是无法生效的。
    • onExit():退出节点时候调用。
    • onExitTransitionDidStart():退出节点而且开始过渡动画时候调用。
    • cleanup():节点对象被清除时候调用。

    从源码上可以确定以下几点:

    • 当运行中的节点新增子节点时,子节点会立即执行OnEnteronEnterTransitionDidFinish
      /**
       * Adds a child to the container with z-order as 0.
       * If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
       * @param child A child node.
       */
      virtual void addChild(Node * child);
      
    • 设置下一个场景的流程:
      void Director::setNextScene()
      {
          _eventDispatcher->dispatchEvent(_beforeSetNextScene);
      
          bool runningIsTransition = dynamic_cast<TransitionScene*>(_runningScene) != nullptr;
          bool newIsTransition = dynamic_cast<TransitionScene*>(_nextScene) != nullptr;
      
          // If it is not a transition, call onExit/cleanup
           if (! newIsTransition)
           {
               if (_runningScene)
               {
                   _runningScene->onExitTransitionDidStart();
                   _runningScene->onExit();
               }
       
               // issue #709. the root node (scene) should receive the cleanup message too
               // otherwise it might be leaked.
               if (_sendCleanupToScene && _runningScene)
               {
                   _runningScene->cleanup();
               }
           }
      
          if (_runningScene)
          {
              _runningScene->release();
          }
          _runningScene = _nextScene;
          _nextScene->retain();
          _nextScene = nullptr;
      
          if ((! runningIsTransition) && _runningScene)
          {
              _runningScene->onEnter();
              _runningScene->onEnterTransitionDidFinish();
          }
          
          _eventDispatcher->dispatchEvent(_afterSetNextScene);
      }
      
    • 设置通知节点(独立绘制的节点,不随场景切换而消失)的流程:
      void Director::setNotificationNode(Node *node)
      {
      	if (_notificationNode != nullptr){
      		_notificationNode->onExitTransitionDidStart();
      		_notificationNode->onExit();
      		_notificationNode->cleanup();
      	}
      	CC_SAFE_RELEASE(_notificationNode);
      
      	_notificationNode = node;
      	if (node == nullptr)
      		return;
      	_notificationNode->onEnter();
      	_notificationNode->onEnterTransitionDidFinish();
          CC_SAFE_RETAIN(_notificationNode);
      }
      
      如果想要删除通知节点可以直接使用Director->getInstance()->setNotificationNode(nullptr)
  • 层级

    Node使用三种层级globalZOrder, localZOrder和orderOfArrival来标记渲染顺序,优先级依次递减,层级越大越后渲染,视觉上处于越上层。

    class Node(Ref)
    {
    protected:	
    #if CC_LITTLE_ENDIAN
        union {
            struct {
                std::uint32_t _orderOfArrival;
                std::int32_t _localZOrder;
            };
            std::int64_t _localZOrder$Arrival;
        };
    #else
        union {
            struct {
                std::int32_t _localZOrder;
                std::uint32_t _orderOfArrival;
            };
            std::int64_t _localZOrder$Arrival;
        };
    #endif
    
        float _globalZOrder;            ///< Global order used to sort the node
    }
    
    • _globalZOrder:标识全局的层级,默认值为0,Node提供了对应的set方法和get方法。
      /**
       Defines the order in which the nodes are renderer.
       Nodes that have a Global Z Order lower, are renderer first.
       
       In case two or more nodes have the same Global Z Order, the order is not guaranteed.
       The only exception if the Nodes have a Global Z Order == 0. In that case, the Scene Graph order is used.
       
       By default, all nodes have a Global Z Order = 0. That means that by default, the Scene Graph order is used to render the nodes.
       
       Global Z Order is useful when you need to render nodes in an order different than the Scene Graph order.
       
       Limitations: Global Z Order can't be used by Nodes that have SpriteBatchNode as one of their ancestors.
       And if ClippingNode is one of the ancestors, then "global Z order" will be relative to the ClippingNode.
      
       @see `setLocalZOrder()`
       @see `setVertexZ()`
      
       @since v3.0
       *
       * @param globalZOrder The global Z order value.
       */
      virtual void setGlobalZOrder(float globalZOrder);
      
      /**
       * Returns the Node's Global Z Order.
       *
       * @see `setGlobalZOrder(int)`
       *
       * @return The node's global Z order
       */
      virtual float getGlobalZOrder() const { return _globalZOrder; }
      
    • _localZOrder:标识同一个父节点下子节点的层级,默认值为0。同样Node提供了相应的get方法和set方法,并且可以在调用addChild方法时指定_localZOrder场景图(节点树)的遍历遵循中序遍历算法_localZOrder < 0的节点定义为左子树,_localZOrder >= 0的节点定义为右子树,也就是说先渲染左子树的节点,再渲染根节点,最后渲染右子树的节点。
      /**
      LocalZOrder is the 'key' used to sort the node relative to its siblings.
      
       The Node's parent will sort all its children based on the LocalZOrder value.
       If two nodes have the same LocalZOrder, then the node that was added first to the children's array will be in front of the other node in the array.
       
       Also, the Scene Graph is traversed using the "In-Order" tree traversal algorithm ( http://en.wikipedia.org/wiki/Tree_traversal#In-order )
       And Nodes that have LocalZOrder values < 0 are the "left" subtree
       While Nodes with LocalZOrder >=0 are the "right" subtree.
       
       @see `setGlobalZOrder`
       @see `setVertexZ`
       *
       * @param localZOrder The local Z order value.
       */
      virtual void setLocalZOrder(std::int32_t localZOrder);
      
      /**
       * Gets the local Z order of this node.
       *
       * @see `setLocalZOrder(int)`
       *
       * @return The local (relative to its siblings) Z order.
       */
      virtual std::int32_t getLocalZOrder() const { return _localZOrder; }
      
      /**
       * Adds a child to the container with a local z-order.
       *
       * If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
       *
       * @param child     A child node.
       * @param localZOrder    Z order for drawing priority. Please refer to `setLocalZOrder(int)`.
       */
      virtual void addChild(Node * child, int localZOrder);
      
    • _orderOfArrival:按到达(加入到场景图)的顺序去标识渲染的顺序。当_globalZOrder_localZOrder都相等时,越晚加入到场景图中的节点,就越后渲染。
  • 常用子类

    • Scene :自定义场景的父类(抽象类),对场景进行渲染等操作。
      /** @class Scene
       * @brief Scene is a subclass of Node that is used only as an abstract concept.
      Scene and Node are almost identical with the difference that Scene has its anchor point (by default) at the center of the screen.
      For the moment Scene has no other logic than that, but in future releases it might have additional logic.
      It is a good practice to use a Scene as the parent of all your nodes.
       
      Scene will create a default camera for you.
      */
      class CC_DLL Scene : public Node
      
    • LayerMenu继承自Layer,提供触摸事件响应。
      /** @class Layer
       * @brief Layer is a subclass of Node that implements the TouchEventsDelegate protocol.
      
      All features from Node are valid, plus the following new features:
      - It can receive iPhone Touches
      - It can receive Accelerometer input
      */
      class CC_DLL Layer : public Node
      
    • Widget:cocos3.0的CocosUI.h下的组件(e.g. Button)都是继承自Widget,提供窗口ui的交互。
      /**
       * @brief Base class for all ui widgets.
       * This class inherent from `ProtectedNode` and `LayoutParameterProtocol`.
       * If you want to implements your own ui widget, you should subclass it.
       */
      class CC_GUI_DLL Widget : public ProtectedNode, public LayoutParameterProtocol
      

【参考资料】
[1] Cocos2D-X游戏开发技术精解 - 第3章 渲染框架
[2] [Cocos2d-X之触摸事件
[3] cocos2dx——节点的渲染(绘制)顺序LocalZOrder、GlobalZOrder、OrderOfArrival_break;的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值