七、CCScene
CCScene一般情况是游戏里面的根节点,称之为"场景",运行游戏时需要通过CCDirector启动第一个场景。当然,游戏稍微复杂一点的话,可能会包含很多个场景,这就涉及到场景的切换,也是通过CCDirector来完成。CCScene是个抽象的概念,也没有可视化显示的功能,对比CCNode,CCScene基本上没有额外的代码:
- // CCScene.h
- #import "CCNode.h"
- @interface CCScene : CCNode
- {
- }
- @end
- // CCScene,m
- #import "CCScene.h"
- #import "Support/CGPointExtension.h"
- #import "CCDirector.h"
- @implementation CCScene
- -(id) init
- {
- if( (self=[super init]) ) {
- CGSize s = [[CCDirector sharedDirector] winSize];
- // 设置position不受anchorPoint影响
- self.isRelativeAnchorPoint = NO;
- // 设置anchorPoint
- anchorPoint_ = ccp(0.5f, 0.5f);
- // 设置CCScene的大小为屏幕大小
- [self setContentSize:s];
- }
- return self;
- }
- @end
可以发现,对比CCNode,CCScene只是重写了init方法而已,而且也只是做了一个简单的设置
常用操作
1.运行第一个场景
我们一般是在应用程序代理AppDelegate的applicationDidFinishLaunching:方法结尾处运行游戏的第一个场景
- [[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];
这里的[HelloWorldLayer scene]返回的是一个CCScene对象
2.替换场景
- [[CCDirector sharedDirector] replaceScene:scene];
这个方法会用新的场景替换旧的场景,cocos2d会释放旧场景的内存,删除旧场景中所有的节点,停止所有动作和消息调度,因此我们不用手动释放旧场景的内存
3.推入和弹出场景
我们知道可以用replaceScene:来运行一个新场景,但是会释放掉旧场景的内存。有时候我们希望在不释放旧场景内存的前提下运行一个新场景,这时候就要用到CCDirector的pushScene:和popScene两个方法了。
1> 使用pushScene:方法推入一个新场景,新场景会层叠在旧场景的上面,但并没有释放旧场景的内存,旧场景继续保留在内存中
- [[CCDirector sharedDirector] pushScene:scene];
2> 使用popScene方法弹出最上层的场景并释放其内存,使保留在内存中的旧场景重新显示出来
- [[CCDirector sharedDirector] popScene];
CCTransitionScene
上面介绍了场景的切换,不过都是瞬间完成的,有时候我们想在场景切换的时候有些过渡效果,即以动画的形式切换场景,我们称之为"场景过渡"。要想做场景过渡效果,就必须用CCTransitionScene的子类,CCTransitionScene本身继承了CCScene,它包含了非常多的子类,每个子类都有不同的场景过渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻页效果。
下面演示一个翻页效果:
- CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene];
- [[CCDirector sharedDirector] replaceScene:page];
意思是在0.5秒的时间内使用翻页效果从旧场景过渡到scene这个新场景,因为CCTransitionScene是CCScene的子类,所以可以作为replaceScene:的参数。
cocos2d中有非常多的过渡效果可以使用,都是CCTransitionScene的子类,类名一般都是以CCTransition开头的。我就不在这里一一介绍每个子类有什么效果,也没有必要,用到时自己再去查API吧。
注意:CCTransitionScene只能使用在replaceScene:和pushScene:的时候,在popScene弹出场景时是不能用这个过渡效果的
节点的生命周期
说到场景过渡,那就不得不说一下节点的生命周期,即一个节点从开始被添加到屏幕上 到 从屏幕中移除的过程,CCNode提供了相应的生命周期方法:
- // 节点被添加到屏幕上 或者 重新显示到屏幕上 时调用
- -(void) onEnter;
- // 调用完onEnter后就会调用此方法,如果使用了场景过渡效果,将在场景过渡完毕后才调用此方法
- -(void) onEnterTransitionDidFinish;
- // 节点从屏幕中移除 或者 暂时离开屏幕 时调用
- -(void) onExit;
下面演示在场景切换时,节点生命周期方法的调用顺序
假设有2个图层RedLayer和BlueLayer,它们分别在不同的场景中。点击RedLayer,就推入BlueLayer所在的场景,点击BlueLayer就弹出BlueLayer所在的场景。我们就在场景切换的过程中观察这2个图层的生命周期。
为了区分这2个图层,我让它们继承了CCLayerColor,分别设置不用的背景颜色,RedLayer为红色,BlueLayer为蓝色。
因为RedLayer和BlueLayer都继承CCLayerColor,而且都需要负责创建自己的图层、负责观察生命周期方法的调用,那么我就先抽出一个继承了CCLayerColor的公共父类BaseLayer,在它里面完成一些公共操作,然后让RedLayer和BlueLayer都继承它
BaseLayer的代码
- // BaseLayer.h
- #import "cocos2d.h"
- @interface BaseLayer : CCLayerColor
- // 用来创建图层所在的场景
- + (CCScene *)scene;
- // 图层的背景颜色,交给子类去实现
- + (ccColor4B)bgColor;
- @end
- // BaseLayer.m
- #import "BaseLayer.h"
- @implementation BaseLayer
- #pragma mark - 初始化场景
- + (CCScene *)scene {
- // 获取当前类的背景颜色
- ccColor4B color = [self bgColor];
- // 根据当前类名创建图层
- BaseLayer *layer = [[self class] layerWithColor:color];
- // 接收触摸输入
- layer.isTouchEnabled = YES;
- CCScene *scene = [CCScene node];
- [scene addChild:layer];
- return scene;
- }
- #pragma mark - 打印生命周期方法
- - (void)onEnter { // _cmd 代表着当前的selector
- [super onEnter];
- // 第一个%@是打印类名,第二个%@是打印方法名
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- - (void)onEnterTransitionDidFinish {
- [super onEnterTransitionDidFinish];
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- - (void)onExit {
- [super onExit];
- NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
- }
- @end
RedLayer的代码
- // RedLayer.h
- #import "BaseLayer.h"
- @interface RedLayer : BaseLayer
- @end
- // RedLayer.m
- #import "RedLayer.h"
- #import "BlueLayer.h"
- @implementation RedLayer
- #pragma mark - 点击红色图层时,跳到蓝色图层所在的场景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 初始化蓝色图层所在的场景
- CCScene *scene = [BlueLayer scene];
- // 推入场景(暂时没有使用过渡效果)
- [[CCDirector sharedDirector] pushScene:scene];
- }
- #pragma mark - 背景颜色为红色
- + (ccColor4B)bgColor {
- return ccc4(255, 0, 0, 255);
- }
- @end
BlueLayer的代码
- // BlueLayer.h
- #import "BaseLayer.h"
- @interface BlueLayer : BaseLayer
- @end
- // BlueLayer.m
- #import "BlueLayer.h"
- @implementation BlueLayer
- #pragma mark - 当点击蓝色图层时,弹出场景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- [[CCDirector sharedDirector] popScene];
- }
- #pragma mark - 背景颜色为蓝色
- + (ccColor4B)bgColor {
- return ccc4(0, 0, 255, 255);
- }
- @end
1.在应用程序加载完毕后,即在AppDelegate的applicationDidFinishLaunching:方法中启动第一个场景 ---- 红色图层所在的场景
- [[CCDirector sharedDirector] runWithScene: [RedLayer scene]];
运行完毕后,效果如下:

生命周期方法打印如下:
- 2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter
- 2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish
2.点击红色图层,跳到蓝色图层所在的场景
这里根据有没有使用过渡效果,要分2种情况
1> 如果没有使用过渡效果
屏幕直接变为蓝色

生命周期方法打印如下:
- 2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit
- 2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter
- 2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish
可以看出,是先移除红色,再添加蓝色
2> 如果使用了过渡效果
先改变下RedLayer中的代码:
- #pragma mark - 点击红色图层时,跳到蓝色图层所在的场景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 初始化蓝色图层所在的场景
- CCScene *scene = [BlueLayer scene];
- // 旧场景一边旋转一边缩小,新场景一边旋转一边方法
- CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];
- // 推入场景(暂时没有使用过渡效果)
- [[CCDirector sharedDirector] pushScene:page];
- }
接下来看一下屏幕效果和打印信息
过渡效果刚开始就会打印:
- 2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter
说明是先初始化并添加BlueLayer
然后中间经历了长达2s的过渡效果:
红色是在一边旋转一边缩小

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

蓝色放大到屏幕大小后

最后会出现以下打印信息:
- 2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit
- 2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish
移除红色,蓝色过渡完毕
3> 点击蓝色图层,弹出蓝色图层所在的场景,重新显示红色图层所在的场景

打印信息如下:
- 2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit
- 2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter
- 2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish
移除蓝色,重新显示红色
七、CCScene的更多相关文章
- cocos2D(七)---- CCScene
		CCScene普通情况是游戏里面的根节点.称之为"场景",执行游戏时须要通过CCDirector启动第一个场景. 当然,游戏略微复杂一点的话.可能会包括非常多个场景,这就涉及到场景 ... 
- 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文
		阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ... 
- CRL快速开发框架系列教程七(使用事务)
		本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ... 
- 《LoadRunner12七天速成宝典》来了
		看到自己的新书又要发行了,算算从09年第一本书开始,不知不觉已经是第四本书了(帮朋友合写的书不算),每次写完之后都会说太累了,不想再写了,但是却又次次反悔,吞下食言的苦果.如果非要说第四本书的感受,那 ... 
- 【SAP业务模式】之ICS(七):IDOC配置
		这是ICS业务模式系列的最后一篇了,主要讲解IDOC的配置. 一.指定EDI传输的供应商逻辑地址 事务代码:WEL1 注意:上面逻辑地址是生产公司+内部客户.有以下两种情形: 1.如果内部客户都是纯数 ... 
- 我的MYSQL学习心得(七) 查询
		我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ... 
- Nodejs之MEAN栈开发(七)---- 用Angular创建单页应用(下)
		上一节我们走通了基本的SPA基础结构,这一节会更彻底的将后端的视图.路由.控制器全部移到前端.篇幅比较长,主要分页面改造.使用AngularUI两大部分以及一些优化路由.使用Angular的其他指令的 ... 
- Go语言实战 - 网站性能优化第一弹“七牛云存储”
		由于用户纷纷反应山坡网的打开速度比较慢,所以两天前我们决定把服务器从linode迁移到阿里云. 整个迁移过程非常平滑,基本上一个小时就完成了.而且阿里云的配套设施提供的也很不错,运行状态监控什么的都有 ... 
- redis成长之路——(七)
		扩展性封装 虽说现在StackExchange.Redis免费,万一到时候和servicestack.redis一样要收费呢,所以先留一口,后续的可以再处理 实例代码点击这里查看 redis成长之路- ... 
随机推荐
- JQ基础练习---图片划过变暗
			简单分享下,划过一张图片其余图片变暗,图片划过变暗的简单效果,JQ实现主要是css写法跟思路变化. <script src="http://ajax.googleapis.com/aj ... 
- 六个前端开发工程师必备的Web设计模式/模块资源(转)
			[导读] Yahoo的设计模式库Yahoo的设计模式库包含了很多可以帮助开发设计人员解决遇到的问题的资源,包括开发中常常需要处理的导航,互动效果及其布局网格等大家常用的组件和模块响应式设计模式库这个响 ... 
- 表单重置reset
			最近一直在做各种页面的“增删改查”,只是在做新增功能的时候,自己一直在使用 reset来清空form表单,原以为这样子的清空方法是万无一失的,可惜最终还是在进行“修改”操作完了之后再“新增”的时候,就 ... 
- JDicom使用指南
			适用条件本指南用于使用JDicom进行环境模拟.产品调试. 一.安装JDicom运行JDicom安装程序之前,需安装JRE 1.3及以上版本.否则,弹出如下图所示报错 安装JRE 1.4:双击运行可执 ... 
- BZOJ1932 [Shoi2007]Setstack 集合堆栈机
			妈呀...clj大爷太强啦! 原来还有set_union和set_intersection这种东西... 于是只要把栈顶的每个元素hash一下记录到一个vector里去就好了 /*********** ... 
- 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。 (异常来自 HRESULT:0x8000401A)。
			检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开 ... 
- 判断数据库内容,在页面显示自定义数据case when
			判断数据库内容,在页面显示自定义数据 case when...then ...else...end 比如:数据库内容是这样: 通过sql语句判断,数据库的name字段,内容是月桂的,显示嫦娥,其他的显 ... 
- <转载>DB2常用命令
			1.数据库的启动.停止 db2start --启动 db2stop [force] --停止 2.与数据库的连接.断开 db2 CONNECT TO DBName [user UserI ... 
- [微软]technet与msdn
			我们搜索一个微软术语,有时定位到technet页面,有时定位到msdn页面.我直观的理解就是technet教人们如何使用微软产品,而msdn指导人们如何开发基于微软产品的软件.那么微软对它们具体定位是 ... 
- Date的转换
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String str = sdf.format(一个date对 ... 
