【吼吼睡cocos2d学习笔记】第五章 - loading场景以及其他
2011-12-13 10:31
531 查看
游戏必然涉及到场景的切换(蜘蛛人不在此列)。
如果新场景在init的时候需要加载大量的资源,在这段时间中用户界面将会失去响应。这对于玩家而言是一个非常糟糕的体验,他可能觉得你把他搞死机了 :)
我们在WOW中进入副本的瞬间其实就涉及到场景的切换,很明显的是暴风雪的程序员并没有让我们体验这种糟糕的感觉,他们会设计一个过场场景来告诉我们加载了百分之多少了。
记住:等待比不知所措要好得多。
先看展示动画:展示动画
由于动画中看不到鼠标点击的操作,所以你可能会觉得有点不知所措。听我来解释一下。
本例涉及到3个场景,源场景,目标场景和过渡场景。
在源场景和目标场景的init方法中都有复杂的浮点数除法运算,这可能会需要3秒钟的时间(模拟器环境下,真机可能更长)。
当源场景被触摸以后,直接使用导演的replaceScene切换到目标场景,你会发现显示帧率的区域停止了跳动,游戏此时进入"失去响应状态"。
在目标场景中我们再次触摸屏幕,此时借助过渡场景来replaceScene到目标场景,loading界面出现,相同的时间后顺利切换到源场景。
来看实现过程,代码结构如下图:
源场景和目标场景其实都是用层来构造的,过程场景是一个CCSecen。
先看FirstLayer中的内容:
使用静态方法scene来构造场景并返回。
zheteng方法负责用三亿个浮点数除法运算来模拟加载大量资源。
在屏幕的触摸中,直接使用导演的replaceScene方法切换到目标场景。
看NextLayer的代码:
和FirstLayer唯一不同的就是,本层使用replaceScene切换到了LoadingScene场景,注意initWithTargetScene这个方法。他出现在LoadingScene类中:
initWithTargetScene类负责构造自身的示例,同时接收一个targetScene类型的参数来指向过渡到的目标场景,这是为了以后多场景扩展而设计的代码。
当然,targetScene不是系统提供的,他其实是我们自定义的一个枚举类型,他出现在LoadingScene.h中:
我们在schedule回调的方法waitLoad中切换到目标场景,有的看官可能要问了,为什么不在init方法中直接使用replaceScene方法呢?这里有两个准则要遵守:
规则一:
永远不要在一个节点的init方法中调用CCDirector的replaceScene方法。
规则二:
请遵守规则一。哈哈,不遵守规则的后果是程序崩溃。Director无法容忍一个节点在初始化的同时进行场景替换。
其实这并没有从根本上解决问题,我们仅仅是做了一次中转而已。
甚至从效率上讲,因为多了一次场景切换,反而增加了系统负担。
上述粗体的字听起来似乎有道理,其实不是这样的。世上总有很有多类似这样的看似有道理的谎言。
虽然我们增加了一个场景,但是从内存管理上而言,反而节省了开支,因为在切换场景的时候,会有一个致命瞬间,在这个瞬间两个场景同时存在于内存中,很明显的是loading场景只会占用很少的资源,你懂得。而且从感官上而言,玩家可能会觉得更容易接受使用loading。
代码下载
如果新场景在init的时候需要加载大量的资源,在这段时间中用户界面将会失去响应。这对于玩家而言是一个非常糟糕的体验,他可能觉得你把他搞死机了 :)
我们在WOW中进入副本的瞬间其实就涉及到场景的切换,很明显的是暴风雪的程序员并没有让我们体验这种糟糕的感觉,他们会设计一个过场场景来告诉我们加载了百分之多少了。
记住:等待比不知所措要好得多。
先看展示动画:展示动画
由于动画中看不到鼠标点击的操作,所以你可能会觉得有点不知所措。听我来解释一下。
本例涉及到3个场景,源场景,目标场景和过渡场景。
在源场景和目标场景的init方法中都有复杂的浮点数除法运算,这可能会需要3秒钟的时间(模拟器环境下,真机可能更长)。
当源场景被触摸以后,直接使用导演的replaceScene切换到目标场景,你会发现显示帧率的区域停止了跳动,游戏此时进入"失去响应状态"。
在目标场景中我们再次触摸屏幕,此时借助过渡场景来replaceScene到目标场景,loading界面出现,相同的时间后顺利切换到源场景。
来看实现过程,代码结构如下图:
源场景和目标场景其实都是用层来构造的,过程场景是一个CCSecen。
先看FirstLayer中的内容:
// // FirstLayer.m // CH05 // // Created by phc on 11-12-12. // Copyright 2011年 hxsoft. All rights reserved. // #import "FirstLayer.h" #import "NextLayer.h" @implementation FirstLayer -(void)dealloc { [super dealloc]; } +(id)scene { CCScene *sc = [CCScene node]; [sc addChild:[FirstLayer node]]; return sc; } //用浮点数除法折腾 -(void)zheteng { float a = 2423; float b = 3432; for (int i = 0; i < 300000000; i++) { a /= b; } } -(id)init { if (self = [super init]) { CCLabelTTF *lbl = [CCLabelTTF labelWithString:@"点击屏幕切换场景(没有loading)" fontName:@"Arial" fontSize:18]; [self addChild:lbl]; CGSize sizeOfWin = [[CCDirector sharedDirector] winSize]; lbl.position = CGPointMake(sizeOfWin.width * 0.5, sizeOfWin.height * 0.5); [self zheteng]; [self setIsTouchEnabled:YES]; } return self; } -(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[CCDirector sharedDirector] replaceScene:[NextLayer scene]]; } @end
使用静态方法scene来构造场景并返回。
zheteng方法负责用三亿个浮点数除法运算来模拟加载大量资源。
在屏幕的触摸中,直接使用导演的replaceScene方法切换到目标场景。
看NextLayer的代码:
// // NextLayer.m // CH05 // // Created by phc on 11-12-12. // Copyright 2011年 hxsoft. All rights reserved. // #import "NextLayer.h" #import "LoadingScene.h" @implementation NextLayer +(id)scene { CCScene *sc = [CCScene node]; [sc addChild:[NextLayer node]]; return sc; } //用浮点数除法折腾 -(void)zheteng { float a = 2423; float b = 3432; for (int i = 0; i < 300000000; i++) { a /= b; } } -(id)init { if (self = [super init]) { [self zheteng]; CCLabelTTF *lbl = [CCLabelTTF labelWithString:@"目标场景,点击屏幕切换场景(有loading)" fontName:@"Arial" fontSize:16]; [self addChild:lbl]; CGSize sizeOfWin = [[CCDirector sharedDirector] winSize]; lbl.position = CGPointMake(sizeOfWin.width * 0.5, sizeOfWin.height * 0.5); [self setIsTouchEnabled:YES]; } return self; } -(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[CCDirector sharedDirector] replaceScene:[LoadingScene initWithTargetScene:FIRSTLAYERTARGET]]; } @end
和FirstLayer唯一不同的就是,本层使用replaceScene切换到了LoadingScene场景,注意initWithTargetScene这个方法。他出现在LoadingScene类中:
// // LoadingScene.m // CH05 // // Created by phc on 11-12-12. // Copyright 2011年 hxsoft. All rights reserved. // #import "LoadingScene.h" #import "FirstLayer.h" #import "NextLayer.h" @implementation LoadingScene -(void)dealloc { [super dealloc]; } +(id)initWithTargetScene:(targetScene)targetSc { return [[[self alloc] initScene:targetSc] autorelease]; } -(id)initScene:(targetScene)targetSc { _targetsc = targetSc; if (self = [super init]) { CCLabelTTF *lbl = [CCLabelTTF labelWithString:@"Loading..." fontName:@"Marker Felt" fontSize:64]; [self addChild:lbl]; CGSize sizeOfWin = [[CCDirector sharedDirector] winSize]; lbl.position = CGPointMake(sizeOfWin.width * 0.5, sizeOfWin.height * 0.5); [self schedule:@selector(waitLoad)]; } return self; } -(void)waitLoad { switch (_targetsc) { case FIRSTLAYERTARGET: [[CCDirector sharedDirector] replaceScene:[FirstLayer scene]]; break; case NEXTLAYERTARGET: [[CCDirector sharedDirector] replaceScene:[NextLayer scene]]; break; default: break; } } @end
initWithTargetScene类负责构造自身的示例,同时接收一个targetScene类型的参数来指向过渡到的目标场景,这是为了以后多场景扩展而设计的代码。
当然,targetScene不是系统提供的,他其实是我们自定义的一个枚举类型,他出现在LoadingScene.h中:
typedef enum { INVALIDTARGET = 0, FIRSTLAYERTARGET = 1, NEXTLAYERTARGET = 2 }targetScene;
我们在schedule回调的方法waitLoad中切换到目标场景,有的看官可能要问了,为什么不在init方法中直接使用replaceScene方法呢?这里有两个准则要遵守:
规则一:
永远不要在一个节点的init方法中调用CCDirector的replaceScene方法。
规则二:
请遵守规则一。哈哈,不遵守规则的后果是程序崩溃。Director无法容忍一个节点在初始化的同时进行场景替换。
其实这并没有从根本上解决问题,我们仅仅是做了一次中转而已。
甚至从效率上讲,因为多了一次场景切换,反而增加了系统负担。
上述粗体的字听起来似乎有道理,其实不是这样的。世上总有很有多类似这样的看似有道理的谎言。
虽然我们增加了一个场景,但是从内存管理上而言,反而节省了开支,因为在切换场景的时候,会有一个致命瞬间,在这个瞬间两个场景同时存在于内存中,很明显的是loading场景只会占用很少的资源,你懂得。而且从感官上而言,玩家可能会觉得更容易接受使用loading。
代码下载
相关文章推荐
- 【吼吼睡cocos2d学习笔记】第五章 - loading场景以及其他
- 【吼吼睡cocos2d学习笔记】第六章 - cocos2d中的层以及层之间的传值
- 【吼吼睡cocos2d学习笔记】第六章 - cocos2d中的层以及层之间的传值
- 【DAY3】shell编程以及linux的其他设置学习笔记
- cocos2d-html5学习笔记(五)--菜单和场景转换
- 【吼吼睡cocos2d学习笔记】第一章 - 介绍cocos2d
- 【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏
- 【Cocos2d-X开发学习笔记】第17期:动作类之跟随动作、可调整速度动作以及动作延时的使用
- python 学习笔记 四 条件, 循环以及其他
- Cocos2d-x学习笔记(2)- 场景的基本元素
- cocos2d-x 2.0.4 学习笔记(一)场景、层、精灵
- Cocos2d-X 学习笔记 11 制作Loading视图
- 【吼吼睡cocos2d学习笔记】第二章 - 开始学习
- 我的Cocos2d-x学习笔记(四)场景转换特效
- Cocos2d-x学习笔记(八)场景切换原理分析
- 【吼吼睡cocos2d学习笔记】第三章 - 基础知识
- cocos2d-x 菜鸟学习笔记四(游戏场景与场景切换)
- IOS cocos2d学习笔记-<七>CCTransitionScene场景切换动画
- 我的Cocos2d-x学习笔记(四)场景转换特效
- python学习笔记——第五章 条件、循环和其他语句