Cocos2d-x 3.2节点类Node详细总结

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


【Node】

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

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

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

继承关系如下:

wKiom1QOafTQMRvyAAAXab9q2nY179.jpg

一个节点的主要特点:

  • 他们可以包含其他的节点对象(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、节点的属性

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

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
/**
  * 位置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、节点的操作

节点的操作有:标记、名字、自定义数据、父节点管理、子节点管理、其他操作管理。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//
/**
  * 标记与名字 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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
/**
  * 动作管理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

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

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
34
35
//
/**
  * 定时器管理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类,增加颜色、透明度的设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//
/**
  * 整合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时,结束查找。

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

使用举例:

1
2
3
4
5
6
7
8
9
//
     //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 });
//

通配符匹配举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
//
     //搜索语法选项
     '//'  : 递归访问所有子节点,   只能放在搜索串的开头位置
     '..'  : 搜索移至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”的节点使用。

1
2
3
4
//
     virtual  void  setGlobalZOrder( float  globalZOrder);
     virtual  float  getGlobalZOrder()  const ;
//

7.2 局部Z顺序

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

父节点将会通过LocalZOrder的值来分辨所有的子节点。如果两个节点有同样的LocalZOrder,那么先加入子节点数组的节点将会显示在后加入的节点的前面。

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

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


8、坐标转换

参考:《Cocos2d-x 3.0坐标系详解


8.1 坐标转换函数

坐标分为两种坐标:

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

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


8.2 举例

1411700156427607.jpg1411700160826914.jpg

  • 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的内部区域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
     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 ;
     }
//


来源网址:http://shahdza.blog.51cto.com/2410787/1550288

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值