【吼吼睡cocos2d学习笔记】第五章 - 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]];

}

使用静态方法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中切换到目标场景。

其实这并没有从根本上解决问题,我们仅仅是做了一次中转而已。

甚至从效率上讲,因为多了一次场景切换,反而增加了系统负担。你会发现在LoadingScene中的帧率显示区依然是卡死的。但是从感觉上而言,玩家可能会觉得更容易接受。

代码下载




 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值