七、CCScene

CCScene一般情况是游戏里面的根节点,称之为"场景",运行游戏时需要通过CCDirector启动第一个场景。当然,游戏稍微复杂一点的话,可能会包含很多个场景,这就涉及到场景的切换,也是通过CCDirector来完成。CCScene是个抽象的概念,也没有可视化显示的功能,对比CCNode,CCScene基本上没有额外的代码:

[java] view plaincopy

  1. // CCScene.h
  2. #import "CCNode.h"
  3. @interface CCScene : CCNode
  4. {
  5. }
  6. @end


[java] view plaincopy

  1. // CCScene,m
  2. #import "CCScene.h"
  3. #import "Support/CGPointExtension.h"
  4. #import "CCDirector.h"
  5. @implementation CCScene
  6. -(id) init
  7. {
  8. if( (self=[super init]) ) {
  9. CGSize s = [[CCDirector sharedDirector] winSize];
  10. // 设置position不受anchorPoint影响
  11. self.isRelativeAnchorPoint = NO;
  12. // 设置anchorPoint
  13. anchorPoint_ = ccp(0.5f, 0.5f);
  14. // 设置CCScene的大小为屏幕大小
  15. [self setContentSize:s];
  16. }
  17. return self;
  18. }
  19. @end

可以发现,对比CCNode,CCScene只是重写了init方法而已,而且也只是做了一个简单的设置

常用操作

1.运行第一个场景

我们一般是在应用程序代理AppDelegate的applicationDidFinishLaunching:方法结尾处运行游戏的第一个场景

[java] view plaincopy

  1. [[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];

这里的[HelloWorldLayer scene]返回的是一个CCScene对象

2.替换场景

[java] view plaincopy

  1. [[CCDirector sharedDirector] replaceScene:scene];

这个方法会用新的场景替换旧的场景,cocos2d会释放旧场景的内存,删除旧场景中所有的节点,停止所有动作和消息调度,因此我们不用手动释放旧场景的内存

3.推入和弹出场景

我们知道可以用replaceScene:来运行一个新场景,但是会释放掉旧场景的内存。有时候我们希望在不释放旧场景内存的前提下运行一个新场景,这时候就要用到CCDirector的pushScene:和popScene两个方法了。

1> 使用pushScene:方法推入一个新场景,新场景会层叠在旧场景的上面,但并没有释放旧场景的内存,旧场景继续保留在内存中

[java] view plaincopy

  1. [[CCDirector sharedDirector] pushScene:scene];

2> 使用popScene方法弹出最上层的场景并释放其内存,使保留在内存中的旧场景重新显示出来

[java] view plaincopy

  1. [[CCDirector sharedDirector] popScene];

CCTransitionScene

上面介绍了场景的切换,不过都是瞬间完成的,有时候我们想在场景切换的时候有些过渡效果,即以动画的形式切换场景,我们称之为"场景过渡"。要想做场景过渡效果,就必须用CCTransitionScene的子类,CCTransitionScene本身继承了CCScene,它包含了非常多的子类,每个子类都有不同的场景过渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻页效果。

下面演示一个翻页效果:

[java] view plaincopy

  1. CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene];
  2. [[CCDirector sharedDirector] replaceScene:page];

意思是在0.5秒的时间内使用翻页效果从旧场景过渡到scene这个新场景,因为CCTransitionScene是CCScene的子类,所以可以作为replaceScene:的参数。

cocos2d中有非常多的过渡效果可以使用,都是CCTransitionScene的子类,类名一般都是以CCTransition开头的。我就不在这里一一介绍每个子类有什么效果,也没有必要,用到时自己再去查API吧。

注意:CCTransitionScene只能使用在replaceScene:和pushScene:的时候,在popScene弹出场景时是不能用这个过渡效果的

节点的生命周期

说到场景过渡,那就不得不说一下节点的生命周期,即一个节点从开始被添加到屏幕上 到 从屏幕中移除的过程,CCNode提供了相应的生命周期方法:

[java] view plaincopy

  1. // 节点被添加到屏幕上  或者 重新显示到屏幕上 时调用
  2. -(void) onEnter;
  3. // 调用完onEnter后就会调用此方法,如果使用了场景过渡效果,将在场景过渡完毕后才调用此方法
  4. -(void) onEnterTransitionDidFinish;
  5. // 节点从屏幕中移除 或者 暂时离开屏幕 时调用
  6. -(void) onExit;

下面演示在场景切换时,节点生命周期方法的调用顺序

假设有2个图层RedLayer和BlueLayer,它们分别在不同的场景中。点击RedLayer,就推入BlueLayer所在的场景,点击BlueLayer就弹出BlueLayer所在的场景。我们就在场景切换的过程中观察这2个图层的生命周期。

为了区分这2个图层,我让它们继承了CCLayerColor,分别设置不用的背景颜色,RedLayer为红色,BlueLayer为蓝色。

因为RedLayer和BlueLayer都继承CCLayerColor,而且都需要负责创建自己的图层、负责观察生命周期方法的调用,那么我就先抽出一个继承了CCLayerColor的公共父类BaseLayer,在它里面完成一些公共操作,然后让RedLayer和BlueLayer都继承它

BaseLayer的代码

[java] view plaincopy

  1. // BaseLayer.h
  2. #import "cocos2d.h"
  3. @interface BaseLayer : CCLayerColor
  4. // 用来创建图层所在的场景
  5. + (CCScene *)scene;
  6. // 图层的背景颜色,交给子类去实现
  7. + (ccColor4B)bgColor;
  8. @end

[java] view plaincopy

  1. // BaseLayer.m
  2. #import "BaseLayer.h"
  3. @implementation BaseLayer
  4. #pragma mark - 初始化场景
  5. + (CCScene *)scene {
  6. // 获取当前类的背景颜色
  7. ccColor4B color = [self bgColor];
  8. // 根据当前类名创建图层
  9. BaseLayer *layer = [[self class] layerWithColor:color];
  10. // 接收触摸输入
  11. layer.isTouchEnabled = YES;
  12. CCScene *scene = [CCScene node];
  13. [scene addChild:layer];
  14. return scene;
  15. }
  16. #pragma mark - 打印生命周期方法
  17. - (void)onEnter { // _cmd 代表着当前的selector
  18. [super onEnter];
  19. // 第一个%@是打印类名,第二个%@是打印方法名
  20. NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
  21. }
  22. - (void)onEnterTransitionDidFinish {
  23. [super onEnterTransitionDidFinish];
  24. NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
  25. }
  26. - (void)onExit {
  27. [super onExit];
  28. NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
  29. }
  30. @end

RedLayer的代码

[java] view plaincopy

  1. // RedLayer.h
  2. #import "BaseLayer.h"
  3. @interface RedLayer : BaseLayer
  4. @end

[java] view plaincopy

  1. // RedLayer.m
  2. #import "RedLayer.h"
  3. #import "BlueLayer.h"
  4. @implementation RedLayer
  5. #pragma mark - 点击红色图层时,跳到蓝色图层所在的场景
  6. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  7. // 初始化蓝色图层所在的场景
  8. CCScene *scene = [BlueLayer scene];
  9. // 推入场景(暂时没有使用过渡效果)
  10. [[CCDirector sharedDirector] pushScene:scene];
  11. }
  12. #pragma mark - 背景颜色为红色
  13. + (ccColor4B)bgColor {
  14. return ccc4(255, 0, 0, 255);
  15. }
  16. @end

BlueLayer的代码

[java] view plaincopy

  1. // BlueLayer.h
  2. #import "BaseLayer.h"
  3. @interface BlueLayer : BaseLayer
  4. @end

[java] view plaincopy

  1. // BlueLayer.m
  2. #import "BlueLayer.h"
  3. @implementation BlueLayer
  4. #pragma mark - 当点击蓝色图层时,弹出场景
  5. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  6. [[CCDirector sharedDirector] popScene];
  7. }
  8. #pragma mark - 背景颜色为蓝色
  9. + (ccColor4B)bgColor {
  10. return ccc4(0, 0, 255, 255);
  11. }
  12. @end

1.在应用程序加载完毕后,即在AppDelegate的applicationDidFinishLaunching:方法中启动第一个场景 ---- 红色图层所在的场景

[java] view plaincopy

  1. [[CCDirector sharedDirector] runWithScene: [RedLayer scene]];

运行完毕后,效果如下:

生命周期方法打印如下:

[java] view plaincopy

  1. 2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter
  2. 2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish

2.点击红色图层,跳到蓝色图层所在的场景

这里根据有没有使用过渡效果,要分2种情况

1> 如果没有使用过渡效果

屏幕直接变为蓝色

生命周期方法打印如下:

[java] view plaincopy

  1. 2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit
  2. 2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter
  3. 2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish

可以看出,是先移除红色,再添加蓝色

2> 如果使用了过渡效果

先改变下RedLayer中的代码:

[java] view plaincopy

  1. #pragma mark - 点击红色图层时,跳到蓝色图层所在的场景
  2. - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  3. // 初始化蓝色图层所在的场景
  4. CCScene *scene = [BlueLayer scene];
  5. // 旧场景一边旋转一边缩小,新场景一边旋转一边方法
  6. CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];
  7. // 推入场景(暂时没有使用过渡效果)
  8. [[CCDirector sharedDirector] pushScene:page];
  9. }

接下来看一下屏幕效果和打印信息

过渡效果刚开始就会打印:

[java] view plaincopy

  1. 2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter

说明是先初始化并添加BlueLayer

然后中间经历了长达2s的过渡效果:

红色是在一边旋转一边缩小

红色完全消失后,蓝色在一边旋转一边放大

蓝色放大到屏幕大小后

最后会出现以下打印信息:

[java] view plaincopy

  1. 2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit
  2. 2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish

移除红色,蓝色过渡完毕

3> 点击蓝色图层,弹出蓝色图层所在的场景,重新显示红色图层所在的场景

打印信息如下:

[java] view plaincopy

  1. 2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit
  2. 2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter
  3. 2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish

移除蓝色,重新显示红色

七、CCScene,布布扣,bubuko.com

时间: 2024-08-17 22:23:24

七、CCScene的相关文章

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

【Beta】 第七次Daily Scrum Meeting

第七次meeting会议 [Beta] 第七次Daily Scrum Meeting 一.本次会议为第七次meeting会议 二.时间:10:00AM-10:20AM 地点:禹州楼 三.会议站立式照片 四.今日任务安排 成员 昨日任务 今日任务 林晓芳 重观界面问题上的美化处理 对现有的东西进行总结,主要是关于此次采用的一些方法.库等等 林清青 与其他组探讨交流进度 对于接下里的任务方向与大家探讨 陈惠 重观界面问题上的美化处理 基于现有的东西进行更深入的完善,例如,如何让闹钟提醒更人性化 郑莹

SpringBoot - 二零一七0421小记

一.SpringBoot使用起来比起SpringMVC更便捷,在注解上的小变化,我记录了下面几个: @Controller + @ResponseBody = SpringMVC中用@RestController来代替前面两个注解,通过这个注解,可以将所有的前端http请求放入SpringBoot的Controller容器中,并返回json格式的数据给前端 @RequestMapping(value={"/hello","/hi"},method=RequestMe

第七课 进程通信

unix_c_07.txt================第七课 进程通信================一.基本概念------------1. 何为进程间通信~~~~~~~~~~~~~~~~~进程间通信(Interprocess Communication, IPC)是指两个,或多个进程之间进行数据交换的过程.2. 进程间通信分类~~~~~~~~~~~~~~~~~1) 简单进程间通信:命令行参数.环境变量.信号.文件.2) 传统进程间通信:管道(fifo/pipe).3) XSI进程间通信:

《七周七数据库》读书分享

# 七周七数据库 读书分享会第一期 2017.02.12 <七周七数据库> - Eric Redmond ## 预备知识 ACID:原子 一致 隔离 持久 CAP原则:一致性 可用性 分区容错性,在分布式环境下,至多只能同时满足其二 "小明,你的数据库作业呢?""我可以今天提交一半的作业,或者明天提交全部的作业,但无法在今天提交全部的作业.""...小明你给我滚出去!" 小知识点: * 原子性:原子性代表中间状态的透明性,想象从a账户

Java 第七章 类和对象 笔记

一.对象的特征--类的属性 每个对象的每个属性都有特定的值 对象的操作--类的方法 二.封装:对象同时具有属性和方法两项特性.     对象的属性和方法通常被封装在一起,共同体现事物的特性,     二者相辅相成,不能分割. 三.类和对象的区别:     类:抽象的概念,是一个模子,确定了对象的属性和方法.    对象:能够看得见摸得着的实物.具有静态和动态特征. 四.定义类的步骤:     1.定义类名      2.定义类的属性 访问修饰符 属性类型 属性名称=默认值:     3.定义类的

TCP/IP四层模型和OSI七层模型的概念

转:http://blog.csdn.net/superjunjin/article/details/7841099/ TCP/IP四层模型 TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.TCP/IP协议簇分为四层,IP位于协议簇的第二层(对应OSI的第三层),TCP位于协议簇的第三层(对应OSI的第四层).   TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求.这4层分别为: 应用层:应用程序间沟通的层,如简单电子邮件传

第七章

第七章 控制发光二极管. 尽管linux 驱动直接和硬件打交道,但并不是linux驱动直接向硬件中的内存写数据,而是与本机的i/o内存进行交互.所谓I/O内存是通过各种接口(PCI, USB.蓝牙以太网等)连接到主机的硬件在主机的内存映射.Linux内核提供了多个与I/O内存交互的函数.Linux内核的内存管理模块负责同步I/O内存与硬件的数据. 每一个连接Linux 的硬件在I/O内存中都会有映射首地址.在使用ioread 32.ioread32等函数读写I/O内存时需要指定这些首地址.Led