与2.x相比,节点类Node的属性和功能做了大幅度的修改与增加

Node类是绝大部分类的父类(并不是所有的类,例如Director类是直接继承Ref类的),如Scene、Layer、Sprite以及精灵集合SpriteBatchNode等等等等的父类都是Node。

Node类包含了一些基本的属性、节点相关、Action动作的执行、以及定时器等相关的操作。

当然Node也有父类,其父类为Ref。

继承关系如下:

一个节点的主要特点:

> 他们可以包含其他的节点对象(addChild, getChildByTag, removeChild, etc)

> 他们可以安排定期的回调(schedule, unschedule, etc)

> 他们可以执行一些动作(runAction, stopAction, etc)

> 子类节点通常意味着(单一的/所有的):

> 重写初始化资源并且可以安排回调

> 创建回调来操作进行的时间

> 重写“draw”来渲染节点

> 节点的属性有:位置、缩放、旋转、倾斜、锚点、内容大小、可见性

下面将介绍一下节点主要常用的一些操作函数,以及新的功能特性。

    (1)节点的属性

    (2)节点的操作

    (3)动作相关Action

    (4)定时器相关schedule

    (5)整合NodeRBGA类

    (6)查找子节点enumerateChildren

    (7)渲染顺序zOrder

    (8)坐标转换

1、节点的属性

节点的属性有:位置、缩放、旋转、倾斜、锚点、内容大小、可见性。

//
/**
* 位置Position
* 设置节点的坐标(x,y).在OpenGL中的坐标
* 增加3D坐标
* 增加标准化坐标设置
*/
virtual void setPosition(const Vec2 &position); //Vec2坐标
virtual void setPosition(float x, float y); //(x,y),比Vec2更有效率
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); //Vec3坐标
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
* 设置节点的放缩比例. 对XYZ轴进行放缩
* 例如一张图片. 放缩它的宽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;
virtual float getScale() const; //当x,y放缩因子相同时,得到该节点的缩放因子 /**
* 旋转Rotation
* 设置节点的旋转角度. 负顺,正逆时针旋转
* 增加3D旋转
*/
virtual void setRotation(float rotation);
virtual float getRotation() const; //增加3D旋转
virtual void setRotation3D(const Vec3& rotation);
virtual Vec3 getRotation3D() const; /**
* 倾斜Skew
* 设置XY轴的倾斜角度
* setRotationalSkew() 模拟Flash的倾斜功能
* setSkew() 使用真正的倾斜功能
*/
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
* setTag : 给节点设置一个编号
* setName : 给节点设置一个名字
*/
virtual void setTag(int tag);
virtual void setName(const std::string& name);
virtual int getTag() const;
virtual std::string getName() const; /**
* 自定义数据UserData/Object
* setUserData : 设置一个用户自定义的数据. 可以为一个数据块, 结构体或者一个对象.
* setUserObject : 设置一个用户自定义的对象. 和userData类似, 但它是一个对象而不是void*
*/
virtual void setUserData(void *userData);
virtual void setUserObject(Ref *userObject);
virtual void* getUserData();
virtual Ref* getUserObject(); /**
* 设置父节点Parent
* setParent , removeFromParent
*/
virtual void setParent(Node* parent);
virtual Node* getParent();
virtual void removeFromParent();
virtual void removeFromParentAndCleanup(bool cleanup); //true则删除该节点的所有动作及回调函数. /**
* 管理子节点Child
* addChild ,
* getChildBy** , getChildren , getChildrenCount
* removeChild , removeAllChildren
* reorderChild , sortAllChildren
*/
//添加子节点
//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;
virtual Vector<Node*>& getChildren(); //获得所有子节点,并以Vector数组返回
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(); //删除所有节点
virtual void removeAllChildrenWithCleanup(bool cleanup); //cleanup为true则删除子节点的所有动作 //重排子节点
//重新排序一个子节点,设定一个新的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

动作管理:运行、暂停、取消等操作。

//
/**
* 动作管理Action
* setActionManager
* runAction , stopAction , getActionByTag , getNumberOfRunningActions
*/
//设置被所有动作使用的ActionManager对象
//如果你设置了一个新的ActionManager, 那么之前创建的动作将会被删除
virtual void setActionManager(ActionManager* actionManager);
virtual ActionManager* getActionManager(); Action* runAction(Action* action); //执行一个动作
Action* getActionByTag(int tag); //获取动作, 根据tag标记
void stopAllActions(); //暂停动作
void stopAction(Action* action); //暂停动作
void stopActionByTag(int tag); //暂停动作
ssize_t getNumberOfRunningActions() const; //获取正在运行的动作数量
//

4、定时器相关schedule

定时器管理,默认定时器、自定义定时器、一次性定时器。

//
/**
* 定时器管理schedule
* setScheduler
* scheduleUpdate : 默认定时器
* schedule : 自定义定时器
* scheduleOnce : 一次性定时器
*/
//设置一个调度器对象,来调度所有的“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); //取消默认定时器
virtual void update(float delta); //update为scheduleUpdate定时器的回调函数. //设置自定义定时器.默认为每秒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);
void schedule(SEL_SCHEDULE selector); //默认为每秒60帧
void scheduleOnce(SEL_SCHEDULE selector, float delay); //只执行一次,delay秒后执行 void unschedule(SEL_SCHEDULE selector); //取消一个自定义定时器
void unscheduleAllSelectors(void); //取消所有定时器
void resume(void); //恢复所有定时器和动作
void pause(void); //暂停所有定时器和动作
//

5、整合NodeRGBA类

整合NodeRGBA类,增加颜色、透明度的设置。

//
/**
* 整合NodeRGBA类
* setOpacity : 透明度
* setColor : 颜色
*/
virtual GLubyte getOpacity() const;
virtual GLubyte getDisplayedOpacity() const;
virtual void setOpacity(GLubyte opacity); virtual const Color3B& getColor() const;
virtual const Color3B& getDisplayedColor() const;
virtual void setColor(const Color3B& color);
//

6、enumerateChildren

新增的Node::enumerateChildren方法,且支持C++ 11的正则表达式

用于枚举某个Node节点的子节点,并让名字符合"name通配符"的子节点执行callback函数。

且callback函数返回类型应该为一个bool值,并且返回为true时,结束查找。

//
virtual void enumerateChildren(const std::string &name, std::function<bool(Node* 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"
//

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

所以:

* Android编译需要NDK R9D以上版本

* Linux编译需要GCC4.9以上版本

* iOS编译需要 Xcode5.1以上版本

7、渲染顺序

在2.x中是使用Zorder来控制节点渲染的先后顺序的。而在3.x中渲染的顺序则是由两个因素决定。

全局Z顺序:GlobalZOrder。所有节点之间对比。

局部Z顺序:LocalZOrder。 兄弟节点之间对比。

且Z顺序越小,最先渲染。

7.1、全局Z顺序

> 定义渲染节点的顺序,拥有全局Z顺序越小的节点,最先渲染。

> 假设:两个或者更多的节点拥有相同的全局Z顺序,那么渲染顺序无法保证。唯一的例外是如果节点的全局Z顺序为零,那么场景图顺序是可以使用的。

> 默认的,所有的节点全局Z顺序都是零。这就是说,默认使用场景图顺序来渲染节点。

> 全局Z顺序是非常有用的当你需要渲染节点按照不同的顺序而不是场景图顺序。

局限性: 全局Z顺序不能够被拥有继承“SpriteBatchNode”的节点使用。

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

7.2、局部Z顺序

> LocalZOrder是“key”(关键)来分辨节点和它兄弟节点的相关性。

> 父节点将会通过LocalZOrder的值来分辨所有的子节点。如果两个节点有同样的LocalZOrder,那么先加入子节点数组的节点将会比后加入的节点先得到渲染,那么先加入的节点会被后加入的节点遮盖[update 20140927]。

> 同样的,场景图使用“In-Order(按顺序)”遍历数算法来遍历。并且拥有小于0的LocalZOrder的值的节点是“left”子树(左子树) 所以拥有大于0的LocalZOrder的值得节点是“right”子树(右子树)。

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

8、坐标转换

参考:http://www.tairan.com/archives/5739

  8.1、坐标转换函数

坐标分为两种坐标:

世界坐标:就是相对节点的世界坐标。

局部坐标:就是相对节点的坐标。

//
/**
* 坐标转换convertTo
* WorldSpace : 世界坐标
* NodeSpace : 局部坐标
*
*/
//把世界坐标, 转换到当前节点的本地坐标系中
//基于Anchor Point, 把基于当前节点的本地坐标系下的坐标, 转换到世界坐标系中
Vec2 convertToNodeSpace(const Vec2& worldPoint) const;
Vec2 convertToNodeSpaceAR(const Vec2& worldPoint) const; //把基于当前节点的本地坐标系下的坐标, 转换到世界坐标系中
//基于Anchor Point. 把世界坐标, 转换到当前节点的本地坐标系中
Vec2 convertToWorldSpace(const Vec2& nodePoint) const;
Vec2 convertToWorldSpaceAR(const Vec2& nodePoint) const; //把触点坐标, 转换到当前节点的本地坐标系中
Vec2 convertTouchToNodeSpace(Touch * touch) const;
Vec2 convertTouchToNodeSpaceAR(Touch * touch) const;
//

  8.2、举例

        

> node1坐标为:(20,40), 锚点(0,0)。

> node2坐标为:(-5,-20),锚点(1,1)。

Vec2 point1 = node1->convertToNodeSpace(node2->getPosition());

结果为:(-25,-60)。(即:相对node1节点坐标位置,的,相对坐标)

分析  :node2相对node1节点的坐标为:(-5,-20) - (20,40) 。

也就是说:node2相对node1的坐标位置。

Vec2 point2 = node1->convertToWorldSpace(node2->getPosition());

结果为:(15,20)。(即:相对node1的世界坐标系统下,的,世界坐标)

分析  :将node1作为参照,转换到世界坐标为:(20,40) + (-5,-20) 。

也就是说:node2的坐标现在被看做是相对node1的坐标位置,然后转换到世界坐标。

8.3、在屏幕触控中的应用 

判断触摸点是否触摸到某个精灵图片sp的内部区域。

//
bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
{
//将触点坐标, 转换为相对节点sp的, 相对坐标
Vec2 point = sp->convertTouchToNodeSpace(touch); //构造sp的尺寸矩形
Size size = sp->getContentSize();
Rect rect = Rect(0, 0, size.width, size.height); //判断触点是否触摸到sp内部
if (rect.containsPoint(point)) {
CCLog("点中");
return true;
} return false;
}
//

cocos2dx[3.2](6) 节点类Node的更多相关文章

  1. [原创]cocos2d-x研习录-第二阶 概念类之节点类(CCNode)

    节点类CCNode在基本概念中并不存在,它是为了建立基本概念之间的关联关系而抽象出来的中间辅助类.这个类在Cocos2D-x中极为重要,它为概念类之间搭建了一座宏伟的桥梁.它的继承关系图如下:     ...

  2. COCOS2D-X学习笔记(一)-----Node类的学习

    Node类(在3.0版本以下叫CCNode):节点类. 本文记录以下几个方法的学习笔记: init()和onEnter()这俩个方法都是CCNode的方法.其区别如下: 1.其被调用的顺序是先init ...

  3. 节点类(CCNode)

    节点与渲染树 回顾前面的介绍,我们已经知道了精灵.层和场景如何构成一个游戏的框架.精灵属于层,层属于场景,玩家与精灵互动,并导致游戏画面在不同场景中切换.把每个环节拼接在一起,我们得到了一个完整的关系 ...

  4. C# 读取xml节点类容

    这是一个测试节点类容的获取 这是控制台代码部分 注意的应用文件 :using.system.Xml using System; using System.Collections.Generic; us ...

  5. Cocos2D-x权威指南:核心类成员CCNode

    节点类(CCNode)是Cocos2D-x中的主要类,继承自CCObject.继承关系如图3-2所看到的. 不论什么须要画在屏幕上的对象都是节点类. 最经常使用的节点类包含场景类(CCScene).布 ...

  6. javascript之DOM(一节点类型Node)

    DOM(Document Object Model)是针对HTML和XML文档的一个API.DOM描述的是一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分.起源于DHML,现为W3C的推 ...

  7. 9 DelayQueueEntry 延时队列节点类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  8. cocos2d-x v3.2 FlappyBird 各个类对象详细代码分析(7)

    今天我们介绍最后两个类 GameOverLayer类 GameLayer类 GameLayer类是整个游戏中最重要的类,由于是整个游戏的中央系统,控制着各个类(层)之间的交互,这个类中实现了猪脚小鸟和 ...

  9. 理解ROS的节点(NODE)

    经过前面的学习,我们已经知道了如何构建一个ROS的包,这篇博客将介绍ROS中的节点的概念. 在继续之前,请按ctrl+alt+t打开一个终端,在里面输入: sudo apt-get install r ...

随机推荐

  1. 多线程-生产者消费者(synchronized同步)

    正解博客:https://blog.csdn.net/u011863767/article/details/59731447 永远在循环(loop)里调用 wait 和 notify,不是在 If 语 ...

  2. Java8 新特性----函数式接口,以及和Lambda表达式的关系

    这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系 ...

  3. 解决Javaweb中HTTP500的问题

    当我们新建一个Web项目后,运行时可能出现HTTP-500的错误如下图所示  一般是由于路径配置出错 即你电脑上的Tomcat版本与代码本身版本不一致或没有配置路径造成的 解决方法如下 一.鼠标右击你 ...

  4. qt5---布局

    QHBoxLayout  水平布局: Header:   #include <QHBoxLayout> qmake:  QT += widgets Inherits:QBoxLayout ...

  5. 数组遍历 forEach 方法

    数组的遍历 遍历数组,将数组中的所有元素都取出来. 使用for 循环执行数组的索引(length-1)相同的次数. var arr=["1", "5", &qu ...

  6. CSS样式,语法,添加方法,文本,字体

    总结一些css的基础知识 ㈠css样式 css:cascading style sheets  层叠样式表 css内容和样式相分离,便于修改样式. ㈡css语法 ㈢css添加方法 ⑴行内添加:放在&l ...

  7. CF 354 div2 B 酒杯金字塔

    B. Pyramid of Glasses time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. Android 属性动画监听事件与一个菜单的例子

    简单监听事件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 3 ...

  9. sqli-labs(46)

    0X01首先我们先来看一下源码 发现查询语句变成了 order by  参数也变成了 sort 看看是什么样的 ()首先看看本关sql语句 $sql = "SELECT * FROM use ...

  10. App可视化埋点技术原理大揭秘

    一.背景 运营者能够对用户行为进行分析的前提,是对大量数据的掌握.在以往,这个数据通常是由开发者在控件点击.页面等事件中,一行行地编写埋点代码来完成数据收集的.然而传统的操作模式每当升级改版时,开发和 ...