五、CCNode

本将主要介绍下CCNode这个类,CCNode是所有节点的基类,其中包括我们常用的CCScene(场景)、CCLayer(图层)、CCSprite(精灵)等,它是一个不能够可视化显示的抽象类,只是用来定义所有节点的公共属性和方法的。本讲纯粹是理论。

首先来看看CCNode的继承结构图,只列举了常用的类

节点的处理

1.创建一个新的节点

[java] view plaincopy

  1. CCNode *node = [CCNode node];

2.添加子节点

[java] view plaincopy

  1. // 先创建子节点
  2. CCNode *childNode = [CCNode node];
  3. // 方法1:直接添加
  4. [node addChild:childNode];
  5. // 方法2:z决定了节点的绘制顺序,按照z值从小到大的顺序来绘制节点,即先绘制z值小的节点,再绘制z值大的节点
  6. // 如果多个节点拥有相同的z值,就按照添加它们的先后顺序进行绘制
  7. [node addChild:childNode z:0];
  8. // 方法3:tag的作用是给节点设置一个标记,父节点可以根据设置的tag标记找到对应的子节点
  9. [node addChild:childNode z:0 tag:100];

3.根据tag找到对应的子节点

[java] view plaincopy

  1. // 如果多个节点拥有相同的tag值,这个方法将返回最先匹配tag值的节点
  2. [node getChildByTag:100];

4.删除子节点

[java] view plaincopy

  1. // 方法1:将子节点childNode从父节点node中移除
  2. // "cleanup"设置为YES代表停止子节点运行的所有动作和消息调度
  3. [node removeChild:childNode cleanup:YES];
  4. // 方法2:根据tag值将对应的子节点从父节点node中移除
  5. [node removeChildByTag:100 cleanup:YES];
  6. // 方法3:移除node中的所有子节点
  7. [node removeAllChildrenWithCleanup:YES];
  8. // 方法4:将childNode从它的父节点中移除
  9. [childNode removeFromParentAndCleanup:YES];

5.重新设置子节点的z值

[java] view plaincopy

  1. [node reorderChild:childNode z:1];

6.停止节点运行的所有动作和消息调度

[java] view plaincopy

  1. [node cleanup];

常用属性和方法

1.添加节点时设置的z值,决定了节点的绘制顺序

[java] view plaincopy

  1. @property(nonatomic,readonly) NSInteger zOrder;

2.节点的旋转角度,默认是0,大于0是顺时针旋转,小于0则是逆时针旋转。子节点会继承父节点的这个属性

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) float rotation;

既然是旋转,肯定是绕着一个点进行旋转,究竟是绕着哪个点旋转,取决于anchorPoint

3.节点X和Y方向的缩放比例,同时影响宽度和高度。子节点会继承父节点的这个属性

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) float scale;

既然是缩放,肯定是绕着一个点进行缩放,究竟是绕着哪个点缩放,取决于anchorPoint

4.节点X方向(即宽度)的缩放比例。子节点会继承父节点的这个属性

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) float scaleX;

5.节点Y方向(即高度)的缩放比例。子节点会继承父节点的这个属性

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) float scaleY;

6.节点的大小(不受scale和rotation影响)

[java] view plaincopy

  1. @property (nonatomic,readwrite) CGSize contentSize

7.节点在父节点中的位置(以父节点左下角为(0, 0))

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) CGPoint position;

cocos2d的坐标系:(0,0)在屏幕的左下角,x值向右正向延伸,y值向上正向延伸.

winSize代表屏幕的尺寸

认真思考一下,不难发现,其实position的含义还是很模糊的。

假设一个节点的大小是20x20,则包含了400个点,那么在400个点中究竟是哪个点在position属性指定的位置上呢?

这个就取决于anchorPoint和isRelativeAnchorPoint属性,如果isRelativeAnchorPoint为NO,节点的左下角会在position属性指定的位置上;如果isRelativeAnchorPoint为YES,position的含义还会受anchorPoint的影响

8.可以称之为"定位点",这个anchorPoint影响的东西很多,比如节点position的含义、节点绕着哪个点进行缩放或旋转,anchorPoint的x、y取值范围都是0到1

[java] view plaincopy

  1. @property(nonatomic,readwrite) CGPoint anchorPoint;

默认情况下,CCSprite、CClayer、CCScene的anchorPoint都为(0.5, 0.5),即默认情况下它们的定位点都是自己的中心点。

下面我分别详细描述下anchorPoint对position、缩放、旋转的影响

1> anchorPoint对position的影响

anchorPoint要对position造成影响,前提条件是isRelativeAnchorPoint为YES

我先做个总结:

* 如果anchorPoint = (0, 0),那么节点的左下角就会在position属性指定的位置上

* 如果anchorPoint = (0.5, 0.5),那么节点的中心点就会在position属性指定的位置上

* 如果anchorPoint = (1, 1),那么节点的右上角就会在position属性指定的位置上

* anchorPoint为其他值,以此类推

下面画图解释一下

[java] view plaincopy

  1. // 红色(red)是蓝色的子节点,所以是以蓝色的左下角位置为坐标原点(0, 0)。假设蓝色的大小是100x100,红色的大小是50x50
  2. red.position = CGPointMake(50, 50); // 可以看出,(50, 50)是在蓝色的正中间

由于anchorPoint的不同,改变了红色在蓝色中的位置

2> anchorPoint对缩放的影响

我先做个总结:

* 如果anchorPoint = (0, 0),那么节点就会绕着自己的左下角进行缩放

* 如果anchorPoint = (0.5, 0.5),那么节点就会绕着自己的中点进行缩放

* 如果anchorPoint = (1, 1),那么节点就会绕着自己的右上角进行缩放

* anchorPoint为其他值,以此类推

下面画图解释一下

[java] view plaincopy

  1. node.scale = 0.5f; // 宽高变为原来的1/2

蓝色代表缩放前,红色代表缩放后

3> anchorPoint对旋转的影响

我先做个总结:

* 如果anchorPoint = (0, 0),那么节点就会绕着自己的左下角进行旋转

* 如果anchorPoint = (0.5, 0.5),那么节点就会绕着自己的中点进行旋转

* 如果anchorPoint = (1, 1),那么节点就会绕着自己的右上角进行旋转

* anchorPoint为其他值,以此类推

下面画图解释一下

[java] view plaincopy

  1. node.rotation = 45; // 顺时针旋转45°

蓝色代表旋转前,红色代表旋转后

9.这个属性决定了anchorPoint是否要影响position

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) BOOL isRelativeAnchorPoint;

* 如果为YES,代表anchorPoint影响position;如果为NO,代表anchorPoint不影响position,那么节点的左下角就会在position属性指定的位置上

* 默认情况下,CCSprite的isRelativeAnchorPoint为YES,CCScene、CCLayer的isRelativeAnchorPoint为NO

10.父节点

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) CCNode* parent;

11.所有的子节点

[java] view plaincopy

  1. @property(nonatomic,readonly) CCArray *children;

12.是否可见

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) BOOL visible;

13.添加节点时设置的标记

[java] view plaincopy

  1. @property(nonatomic,readwrite,assign) NSInteger tag;

14.返回节点的边界(包含position和大小)

[java] view plaincopy

  1. - (CGRect) boundingBox;

动作的处理

动作是指在特定时间内完成移动、缩放、旋转等操作的行为。CCNode可以运行动作实现一些动画效果。

1.运行动作

[java] view plaincopy

  1. -(CCAction*) runAction: (CCAction*) action;

[java] view plaincopy

  1. // 初始化一个平移动作,这是向左边移动100的距离
  2. CCAction *action = [CCMoveBy actionWithDuration:2 position:CGPointMake(-100, 0)];
  3. // 可以给动作设置一个标记
  4. action.tag = 100;
  5. // 运行动作
  6. [node runAction:action];

当动作执行完毕后,会自动从节点上删除

2.停止动作

停止节点上的所有动作

[java] view plaincopy

  1. -(void) stopAllActions;

停止某个特定的动作

[java] view plaincopy

  1. -(void) stopAction: (CCAction*) action;

根据tag停止对应的动作

[java] view plaincopy

  1. -(void) stopActionByTag:(NSInteger) tag;

3.根据tag获取对应的动作

[java] view plaincopy

  1. -(CCAction*) getActionByTag:(NSInteger) tag;

4.节点上当前包含的动作总数

[java] view plaincopy

  1. -(NSUInteger) numberOfRunningActions;

消息调度

节点可以进行消息调度,也就是指系统会每隔一段时间调用一次节点的某个方法。节点的消息调度是很常用的,比如一个子弹射出去了,我们需要隔一段时间就调用子弹的某个方法来改变的子弹的位置

为了说明消息调度的用法,我定义一个子弹类,因为子弹是看得见的,所以应该继承CCSprite,而不是继承CCNode

[java] view plaincopy

  1. // Bullet.h
  2. #import "CCSprite.h"
  3. @interface Bullet : CCSprite
  4. @end

1.最简单的做法是直接调用节点的scheduleUpdate方法,就可以开始消息调度

[java] view plaincopy

  1. #import "Bullet.h"
  2. @implementation Bullet
  3. - (id)init {
  4. if (self = [super init]) {
  5. // 在节点初始化的时候开始消息调度
  6. [self scheduleUpdate];
  7. }
  8. return self;
  9. }
  10. - (void)update:(ccTime)delta {
  11. // 在这里改变子弹的位置
  12. // ....
  13. }
  14. @end

当调用了scheduleUpdate方法,系统会以每帧的频率调用一次update:方法(方法名和参数都是固定的),意思是每次刷帧都会调用一次。参数delta代表上次调用方法到现在所经过的时间

2.设置消息调度的优先级

[java] view plaincopy

  1. -(void) scheduleUpdateWithPriority:(NSInteger)priority;

优先级默认为0,系统是按照优先级从低到高的顺序调用update:方法

下面举个例子:

[java] view plaincopy

  1. // 节点A
  2. [nodeA scheduleUpdate];
  3. // 节点B
  4. [nodeB scheduleUpdateWithPriority:-1];
  5. // 节点C
  6. [nodeC scheduleUpdateWithPriority:1];

节点A、B、C都需要以每帧的频率调用update:方法,但是有顺序之分:最先调用节点B的update:方法,因为节点B的优先级最低;然后调用节点A的update:方法,因为节点A为默认优先级0;最后调用节点C的update:,因为节点C的优先级最高

3.如果想在消息调度时调用另外一个方法,或者不想以每帧的频率调用该方法,应该采取下面这种做法

[java] view plaincopy

  1. - (id)init {
  2. if (self = [super init]) {
  3. // 开始消息调度
  4. // [self schedule:@selector(changePosition:)];  // 以每帧的频率调用changePosition:方法
  5. [self schedule:@selector(changePosition:) interval:0.2f]; // 每隔0.2秒就调用changePosition:方法
  6. }
  7. return self;
  8. }
  9. - (void)changePosition:(ccTime)delta {
  10. // do something here
  11. }

4.取消消息调度

取消调用update:方法

[java] view plaincopy

  1. -(void) unscheduleUpdate;

取消调用特定的方法

[java] view plaincopy

  1. -(void) unschedule: (SEL) s;

取消调用所有的方法(包括update:)

[java] view plaincopy

    1. -(void) unscheduleAllSelectors;

五、CCNode,布布扣,bubuko.com

时间: 2024-10-20 12:42:41

五、CCNode的相关文章

cocos2D(五岁以下儿童)---- CCNode

本将主要介绍下CCNode这个类.CCNode是全部节点的基类,当中包含我们经常使用的CCScene(场景).CCLayer(图层).CCSprite(精灵)等.它是一个不可以可视化显示的抽象类,仅仅是用来定义全部节点的公共属性和方法的.本讲纯粹是理论. 首先来看看CCNode的继承结构图,仅仅列举了经常使用的类 节点的处理 1.创建一个新的节点 [java] view plaincopy CCNode *node = [CCNode node]; 2.加入子节点 [java] view pla

第四十一天 一乐在其中—Android的小游戏打飞机(五)添加背景

8月10日,晴."寒蝉凄切,对长亭晚,骤雨初歇." 上篇已经加载了敌机,本篇主要添加背景画面. 本篇要用到的几个函数讲解: 1.addChild(CCNode child, int z):两个参数,第一个要加入场景的对象,第二个是绘制层的顺序,默认参数值为0,表示最高优先层导入,该值越大表示该层在最后加载(在最高一层),一般背景图层是首先加载,其它元素在加载在背景层上面.因为背景在后面加载的话,会覆盖掉前面加载的元素,看不到想要的图层组合效果. 2.schedule(String se

传智播客C++第五期培训视频教程免费下载

C/C++的应用领域几乎无处不在,服务器,嵌入式,物联网,移动互联网,信息安全,游戏,基本上大小通吃.C/C++市场份额高达26%,也就是每四个程序员就有一个C/C++程序员.市场需求量非常大,而且工资高于其他语言.课程讲师:尹成课程内容:C语言 15天1.C语言概述,学习方法,开发环境搭建,HelloWorld案例分析,常量与变量;2.数据类型,数据类型转换,数据输入与输出;3.C语言运算符,C语言操作符;4.C语言表达式,表达式优先级;5.C语言流程控制,分支,顺序,循环逻辑控制;6.函数概

Cocos2d-x学习笔记(五)CCLayer分析及输入事件处理(触摸、重力传感器、按键)

原创文章,转载请注明出处:http://blog.csdn.net/sfh366958228/article/details/38733415 简介 上一讲我们简单的介绍了CCScene,这一讲我们继续来看另一个核心组件CCLayer,他和CCScene有些类似,都是用来收纳其他节点,但是按照层次来说的话,CCLayer应该包含在CCScene之中.老规矩,我们从代码看起. 源码分析 class CC_DLL CCLayer : public CCNode, public CCTouchDele

聚焦新相亲时代:女孩在京有五六套房哭着想嫁富2代

2017-09-20 07:31:00 来源: 中国青年报(北京)        举报 6984 分享到: 易信 微信 QQ空间 微博 更多 用微信扫码二维码 分享至好友和朋友圈 T + - (原标题:中青报聚焦新相亲时代:2亿人及其背后家庭组成的"擂台") 石家庄某相亲角.视觉中国 资料 平均算下来,每一分钟里,国内有22对新人拿着户口本走向民政局,进入婚姻生活:同时,8对夫妻在另外一个窗口签下离婚协议. 根据民政部公布的数字,中国的结婚率和离婚率曲线渐渐逼近一个闭合的大于号.婚姻的

今年黑科技趋势最具的五个看点

CES 2017年人工智能引爆全球最火黑科技盛会 CES 2017 1月5日-8日在美国拉斯维加斯举行,数千家企业.几十万人将参与到这次科技的狂欢秀中.本文为埃森哲技术总监带来的关于本年度CES 的5大看点.他认为:人工智能将统治本年度的CES,变得无处不在.另外,他还分析了智能助理.物联网安全.虚拟现实等多个领域在本届大会上的表现. 2017 年国际消费电子展(CES 2017)将于1月5号拉开帷幕,在这个荒漠之城举办为期5天的展会,保守估计会吸引超过177000名参会者. 这也是一年之中唯一

(十五)PL/SQL事务

数据库事务是一个工作的原子单元,其可以由一个或多个相关的SQL语句组成.所谓的原子性就是数据库的修改所带来的构成事务的SQL语句可以集体被提交,即永久到数据库或从数据库中(撤消)回滚.一个成功执行的SQL语句和提交的事务不一样.即使一个SQL语句执行成功,除非包含该语句的事务被提交,但也可以回滚和声明(S)的所有更改可以撤消. 一.开始事务事务都有开始和结束.事务开始时有下列事件之一:  连接到数据库后执行的第一个SQL语句.  在事务完成之后发出每一个新的SQL语句完成. 二.提交事务事务是通

每周进度条(第十五周)

第十五周进度条   第十五周 所花时间 1h 代码量(行)  100 博客量(篇)  1 学到的知识 对图片的处理 在Android程序中加入图片

201405644 嵌入式程序设计第五周学习总结

嵌入式课程设计第五周学习总结 标准 I/O 编程 标准 I/O 提供流缓冲的目的是尽可能减少使用 read()和 write()等系统调用的数量.标准 I/O 提供了 3 种类型 的缓冲存储.全缓冲.行缓冲.不带缓冲. 打开文件 打开文件有三个标准函数,分别为:fopen().fdopen()和 freopen().其中 fopen()可以指定打开文件的路径和模式,fdopen()可以指定打开的文件描述符和模式,而 freopen() 除可指定打开的文件.模式外,还可指定特定的 I/O 流. f