Cocos2d-x 3.2节点类Node详细介绍

2015年03月24日 15:43 0 点赞 0 评论 更新于 2025-11-21 18:28

与2.x版本相比,节点类Node的属性和功能进行了大幅度的修改与扩展。

Node类概述

Node类是Cocos2d-x中绝大部分类的父类,但并非所有类,例如Director类直接继承自Ref类。像Scene、Layer、Sprite以及精灵集合SpriteBatchNode等类的父类都是Node。Node类包含了一些基本属性、节点相关操作、Action动作执行以及定时器等相关功能。Node类的父类为Ref。

节点的主要特点

  • 包含子节点:可以通过addChildgetChildByTagremoveChild等方法来包含和管理其他节点对象。
  • 安排定期回调:能够使用scheduleunschedule等方法安排定期的回调。
  • 执行动作:可以通过runActionstopAction等方法执行各种动作。

子类节点的常见操作

  • 重写初始化资源并且安排回调。
  • 创建回调来处理时间操作。
  • 重写draw方法来渲染节点。

节点的属性

节点具有位置、缩放、旋转、倾斜、锚点、内容大小、可见性等属性。下面将详细介绍这些属性及相关操作函数,同时还会介绍节点的操作、动作相关、定时器相关、整合NodeRBGA类、查找子节点、渲染顺序和坐标转换等内容。

1、节点的属性

位置(Position)

设置节点的坐标(x, y),在OpenGL中的坐标。在Cocos2d-x 3.2中增加了3D坐标和标准化坐标设置。

// Vec2坐标
virtual void setPosition(const Vec2 &position);
// (x, y),比Vec2更有效率
virtual void setPosition(float x, float y);
virtual void setPositionX(float x);
virtual void setPositionY(float y);
virtual const Vec2& getPosition() const;
virtual void  getPosition(float* x, float* y) const;
virtual float getPositionX(void) const;
virtual float getPositionY(void) const;

// 增加3D坐标
virtual void setPosition3D(const Vec3& position);
virtual Vec3 getPosition3D() const;
virtual void setPositionZ(float positionZ);
virtual float getPositionZ() const;

// 增加标准化坐标设置
// Node的位置像素会根据它的父节点的尺寸大小计算
// Size s = getParent()->getContentSize();
// _position = pos * s;
virtual void setNormalizedPosition(const Vec2 &position);
virtual const Vec2& getNormalizedPosition() const;

放缩(Scale)

设置节点在X、Y、Z轴上的放缩比例。

virtual void setScaleX(float scaleX);              // 放缩宽X
virtual void setScaleY(float scaleY);              // 放缩高Y
virtual void setScaleZ(float scaleZ);              // 放缩深Z
virtual void setScale(float scaleX, float scaleY); // X放缩fScaleX倍,Y放缩fScaleY倍
virtual void setScale(float scale);                // XYZ同时放缩scale倍
virtual float getScaleX() const;
virtual float getScaleY() const;
virtual float getScaleZ() const;
// 当x, y放缩因子相同时,得到该节点的缩放因子
virtual float getScale()  const;

旋转(Rotation)

设置节点的旋转角度,负角度为顺时针旋转,正角度为逆时针旋转。在3.2版本中增加了3D旋转功能。

virtual void setRotation(float rotation);
virtual float getRotation() const;

// 增加3D旋转
virtual void setRotation3D(const Vec3& rotation);
virtual Vec3 getRotation3D() const;

倾斜(Skew)

设置节点在X、Y轴的倾斜角度,提供了模拟Flash倾斜功能和真正的倾斜功能。

virtual void setSkewX(float skewX); // 水平旋转倾斜,负顺时针变形
virtual void setSkewY(float skewY); // 垂直旋转倾斜
virtual void setRotationSkewX(float rotationX);
virtual void setRotationSkewY(float rotationY);
virtual float getSkewX() const;
virtual float getSkewY() const;
virtual float getRotationSkewX() const;
virtual float getRotationSkewY() const;

锚点(AnchorPoint)

锚点就像一枚图钉,将图片钉在屏幕上,而锚点就是图片的坐标。(0, 0)表示左下角,(1, 1)表示右上角,默认的锚点是(0.5, 0.5),即节点的正中心。

// 标准化的锚点
virtual void setAnchorPoint(const Vec2& anchorPoint);
// 标准化的锚点
virtual const Vec2& getAnchorPoint() const;
// 返回绝对像素的锚点,即屏幕坐标
virtual const Vec2& getAnchorPointInPoints() const;
// 是否忽略锚点的设置
// 若忽略锚点设置,锚点永远为(0, 0)
// 默认值是false,但是在Layer和Scene中是true
// 这是一个内部方法,仅仅被Layer和Scene使用,不要自行调用!
virtual void ignoreAnchorPointForPosition(bool ignore);
virtual bool isIgnoreAnchorPointForPosition() const;

内容大小(ContentSize)

contentSize不受节点缩放或旋转的影响,所有的节点都有大小,图层和场景的大小与屏幕大小相同。

virtual void setContentSize(const Size& contentSize);
virtual const Size& getContentSize() const;

可见性(Visible)

设置节点的可见性。

virtual void setVisible(bool visible);
virtual bool isVisible() const;

2、节点的操作

标记与名字(Tag and Name)

为节点设置编号和名字,方便后续查找和管理。

virtual void setTag(int tag);
virtual void setName(const std::string& name);
virtual int getTag() const;
virtual std::string getName() const;

自定义数据(UserData/Object)

可以为节点设置自定义的数据或对象。

virtual void setUserData(void *userData);
virtual void setUserObject(Ref *userObject);
virtual void* getUserData();
virtual Ref* getUserObject();

设置父节点(Parent)

管理节点的父节点关系。

virtual void setParent(Node* parent);
virtual Node* getParent();
virtual void removeFromParent();
// true则删除该节点的所有动作及回调函数
virtual void removeFromParentAndCleanup(bool cleanup);

管理子节点(Child)

添加、获取、删除和重排子节点。

// 添加子节点
// localZOrder   Z轴顺序为了绘画的优先权
// tag           节点编号,可通过tag获取子节点
// name          节点名字,可通过name获取子节点
virtual void addChild(Node * child);
virtual void addChild(Node * child, int localZOrder);
virtual void addChild(Node* child, int localZOrder, int tag);
virtual void addChild(Node* child, int localZOrder, const std::string &name);

// 获取子节点
virtual Node* getChildByTag(int tag) const;
virtual Node* getChildByName(const std::string& name) const;
// 获得所有子节点,并以Vector数组返回
virtual Vector<Node*>& getChildren();
// 子节点总数
virtual ssize_t getChildrenCount() const;

// 删除子节点
virtual void removeChild(Node* child, bool cleanup = true);
virtual void removeChildByTag(int tag, bool cleanup = true);
virtual void removeChildByName(const std::string &name, bool cleanup = true);
// 删除所有节点
virtual void removeAllChildren();
// cleanup为true则删除子节点的所有动作
virtual void removeAllChildrenWithCleanup(bool cleanup);

// 重排子节点
// 重新排序一个子节点,设定一个新的z轴的值
// child         它必须是已经添加的
// localZOrder   Z轴顺序为了绘画优先级
virtual void reorderChild(Node * child, int localZOrder);
// 重新排序所有子节点
virtual void sortAllChildren();

其他操作管理

// 节点开始进入舞台时调用,即创建时调用
virtual void onEnter();
// 节点进入舞台后调用,即创建完后调用
virtual void onEnterTransitionDidFinish();
// 节点离开舞台时调用,即移除时调用
virtual void onExit();
// 节点离开舞台前调用
virtual void onExitTransitionDidStart();
// 绘制节点
virtual void draw() final;
// 递归访问所有子节点,并重新绘制
virtual void visit() final;
// 返回包含Node(节点)的Scene(场景)
// 若不属于任何的场景,它将返回nullptr
virtual Scene* getScene() const;
// 返回节点在父节点坐标中的矩形边界框
virtual Rect getBoundingBox() const;
// 暂停所有的活动着的动作和调度器
virtual void cleanup();

3、动作相关Action

动作管理主要包括运行、暂停、取消等操作。

// 设置被所有动作使用的ActionManager对象
// 如果你设置了一个新的ActionManager,那么之前创建的动作将会被删除
virtual void setActionManager(ActionManager* actionManager);
virtual ActionManager* getActionManager();

// 执行一个动作
Action* runAction(Action* action);
// 获取动作,根据tag标记
Action* getActionByTag(int tag);
// 暂停所有动作
void stopAllActions();
// 暂停指定动作
void stopAction(Action* action);
// 暂停指定tag的动作
void stopActionByTag(int tag);
// 获取正在运行的动作数量
ssize_t getNumberOfRunningActions() const;

4、定时器相关schedule

定时器管理包括默认定时器、自定义定时器和一次性定时器。

// 设置一个调度器对象,来调度所有的“update”和定时器
// 如果你设置了一个新的调度器,那么之前创建的timers/update将会被删除
virtual void setScheduler(Scheduler* scheduler);
// 得到调度器对象
virtual Scheduler* getScheduler();

// 开启默认定时器,刷新次数为60次/秒,即每秒60帧
// 与update(float delta)回调函数相对应
// 给予定时器优先级priority,其中priority越小,优先级越高
void scheduleUpdate(void);
void scheduleUpdateWithPriority(int priority);
// 取消默认定时器
void unscheduleUpdate(void);
// update为scheduleUpdate定时器的回调函数
virtual void update(float delta);

// 设置自定义定时器,默认为每秒60帧
// interval  :  每隔interval秒,执行一次
// repeat    :  重复次数
// delay     :  延迟时间,即创建定时器delay后开始执行
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
void schedule(SEL_SCHEDULE selector, float interval);
// 默认为每秒60帧
void schedule(SEL_SCHEDULE selector);
// 只执行一次,delay秒后执行
void scheduleOnce(SEL_SCHEDULE selector, float delay);
// 取消一个自定义定时器
void unschedule(SEL_SCHEDULE selector);
// 取消所有定时器
void unscheduleAllSelectors(void);
// 恢复所有定时器和动作
void resume(void);
// 暂停所有定时器和动作
void pause(void);

6、enumerateChildren

新增的Node::enumerateChildren方法,支持C++ 11的正则表达式,用于枚举某个Node节点的子节点,并让名字符合”name通配符”的子节点执行callback函数。callback函数返回类型应该为一个bool值,并且返回为true时,结束查找。

virtual void enumerateChildren(const std::string &name, std::function<bool(Node*)> callback) const;

// 使用举例:
// Find nodes whose name is ‘nameToFind’ and end with digits
node->enumerateChildren("nameToFind[[:digit:]]+",
[](Node* node) -> bool { … return false; // return true to stop at first match });
// Find nodes whose name is ‘nameToFind’ and end with digits recursively
node->enumerateChildren("nameToFind[[:digit:]]+",
[](Node* node) -> bool { … return false; // return true to stop at first match });

// 通配符匹配举例:
// 搜索语法选项
// ‘//’ : 递归访问所有子节点,只能放在搜索串的开头位置
// ‘..’ : 搜索移至node的父节点,只能放在某个字符串的结束位置
// ‘/’  : 搜索移至node的子节点,可以放在任何位置,除了搜索串的开头位置
// 代码举例
enumerateChildren("//MyName", …)     : 递归访问Node的所有子节点,查找匹配 “MyName” 的子节点
enumerateChildren("[[:alnum:]]+", …) : 在Node的儿子节点中查找,所有项
enumerateChildren("A[[:digit:]]", …) : 在Node的儿子节点中查找,名字为 “A0″,”A1″,…,”A9″ 的子节点
enumerateChildren("Abby/Normal", …)  : 在Node的孙子节点中查找,其节点为”Normal”,且父节点为”Abby”
enumerateChildren("//Abby/Normal", …): 递归访问Node的所有子节点,其节点为”Normal”,且父节点为”Abby”

注意事项

使用gcc V4.8或更低版本构建的程序运行时会崩溃。由于OTHER_LDFLAGS不能在Xcode 6 beta3中使用,在iOS上我们使用包括64位库文件fat library,但Xcode 5.0或更低版本不支持这种方式。因此:

  • Android编译需要NDK R9D以上版本。
  • Linux编译需要GCC 4.9以上版本。
  • iOS编译需要Xcode 5.1以上版本。

7、渲染顺序

在2.x中使用Zorder来控制节点渲染的先后顺序,而在3.x中渲染顺序由全局Z顺序(GlobalZOrder)和局部Z顺序(LocalZOrder)两个因素决定,且Z顺序越小,最先渲染。

全局Z顺序

定义渲染节点的顺序,全局Z顺序越小的节点最先渲染。如果两个或更多节点拥有相同的全局Z顺序,渲染顺序无法保证,但如果节点的全局Z顺序为零,则使用场景图顺序渲染。默认情况下,所有节点的全局Z顺序都是零。需要注意的是,全局Z顺序不能被继承自SpriteBatchNode的节点使用。

virtual void setGlobalZOrder(float globalZOrder);
virtual float getGlobalZOrder() const;

局部Z顺序

LocalZOrder用于区分节点与其兄弟节点的相关性。父节点会根据LocalZOrder的值来区分所有子节点。如果两个节点的LocalZOrder相同,先加入子节点数组的节点将显示在后加入节点的前面。场景图使用“In-Order(按顺序)”遍历树算法,LocalZOrder小于0的节点属于左子树,大于0的节点属于右子树。

// 设置这个节点的局部Z顺序(相对于兄弟节点)
virtual void setLocalZOrder(int localZOrder);
virtual int getLocalZOrder() const;

作者信息

menghao

menghao

共发布了 3994 篇文章