博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[cocos2d]场景切换以及切换进度显示
阅读量:4498 次
发布时间:2019-06-08

本文共 4724 字,大约阅读时间需要 15 分钟。

本文主要分两个部分叙述,第一是场景切换,第二是场景切换的进度显示。

一、场景切换

参考learn-iphone-and-ipad-cocos2d-game-development 第五章内容

cocos2d可以使用CCDirector replaceScene替换场景。切换场景时节点会调用CCNode的三个方法

onEnter //节点调用init方法后调用此方法(使用了CCTransitionScene的话,将在过渡效果后调用此方法)

onEnterTransitionDidFinish //调用onEnter后调用此方法(使用了CCTransitionScene,将在过渡效果后调用此方法

onExit//节点调用dealloc方法前调用此方法(使用CCTransitionScene,将在过渡效果结束后调用此方法)

对于两个Scene,scene1和scene2

调用次序为

1.scene:scene2

2.init scene2

3.onEnter scene2

4.过渡效果

5.onExit scene1

6.onEnterTransitionDidFinish scene2

7.dealloc scene1

由此可见scene1在scene加载完后调用dealloc,这意味着scene1的内存会一直保存到scene2生成完。

当场景使用的内存较多的时候,切换就需要谨慎起来了。

解决方法:

1、scene2的onEnterTransitionDidFinish里面schedule一个方法,在update里面分配内存,这样的话就会在下一帧或者更后的时候分配内存,此时scene1的内存已经释放了。

2、scene1的onExit里面释放尽量多的内存

3、使用中间场景

4、等等

 

中间场景使用方法:

scene1切换到loadingScene,loadingScene 在init的时候schedule一个方法,在update方法里面切换到scene2

1 #import 
2 #import "cocos2d.h" 3 4 typedef enum 5 { 6 TargetSceneINVALID = 0, 7 TargetSceneScene1, 8 TargetSceneScene2, 9 TargetSceneMAX,10 } TargetScenes;11 12 @interface LoadingScene : CCLayer13 {14 TargetScenes targetScene_;15 }16 17 +(id) sceneWithTargetScene:(TargetScenes)targetScene;18 -(id) initWithTargetScene:(TargetScenes)targetScene;19 20 @end
LoadingScene.h

 

1 #import "LoadingScene.h" 2 #import "Scene1.h" 3 #import "Scene2.h" 4  5  6 @interface LoadingScene (PrivateMethods) 7 -(void) update:(ccTime)delta; 8 @end 9 10 @implementation LoadingScene{11 12 }13 14 +(id) sceneWithTargetScene:(TargetScenes)targetScene;15 {16     CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);17     18     return [[[self alloc] initWithTargetScene:targetScene] autorelease];19     //或者这样20     //return [[[LoadingScene alloc] initWithTargetScene:targetScene] autorelease];21 }22 23 -(id) initWithTargetScene:(TargetScenes)targetScene24 {25     if ((self = [super init]))26     {27         targetScene_ = targetScene;28         29         CCLabelTTF* label = [CCLabelTTF labelWithString:@"Loading ..." fontName:@"Marker Felt" fontSize:64];30         CGSize screenSize = [[CCDirector sharedDirector] winSize];31         label.position = CGPointMake(screenSize.width / 2, screenSize.height / 2);32         [self addChild:label];   33        //在加载目标场景前至少等1帧34      //因为:1、直接加载会崩溃 2、精灵(也就是label)不是显示35         [self scheduleUpdate];36     }  37     return self;38 }39 40 -(void) update:(ccTime)delta41 {42 43     // 因为要切换场景,所以这里不是必要的。这样做是以防万一。44         [self unschedule:_cmd];45     46     // 根据需求加载目标场景,这样就代码可以用在多种情况下了47         switch (targetScene_)48         {49             case TargetSceneMainScene:50                 [[CCDirector sharedDirector] replaceScene:[Scene1 scene]];51                 break;52             case TargetSceneExamScene:53                 [[CCDirector sharedDirector] replaceScene:[Scene2 scene]];54                 break;55                 56             default:57                 // 如果使用了不恰当的数值,这会警告你58                 NSAssert2(nil, @"%@: unsupported TargetScene %i", NSStringFromSelector(_cmd), targetScene_);59                 break;60         }61       62         // Tip: example usage of the INVALID and MAX enum values to iterate over all enum values63         for (TargetScenes i = TargetSceneINVALID + 1; i < TargetSceneMAX; i++)64         {65         }66 67 }68 69 -(void) dealloc70 {71     CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);72     // don't forget to call "super dealloc"73     [super dealloc];74 }75 76 @end
LoadingScene.m

 

1 #import "Scene1.h" 2 #import "LoadingScene.h" 3  4  5 @implementation Scene1 6  7 +(id)scene{ 8     CCScene *scene = [CCScene node]; 9     Scene1*layer = [Scene1 node];10     [scene addChild:layer];11     return scene;12 }13 14 -(id)init{15     if ((self = [super init])) {16         CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);17         18         CGSize size = [[CCDirector sharedDirector] winSize];19         20         CCLabelTTF *titlelabel = [CCLabelTTF labelWithString:@"游戏" fontName:@"Heiti SC" fontSize:30];21         titlelabel.color = ccBLUE;22 23         titlelabel.position = CGPointMake(size.width * 0.5f, size.height * 0.7f);24         [self addChild:titlelabel];      25         CCLabelTTF *label = [CCLabelTTF labelWithString:@"点击开始游戏" fontName:@"Heiti SC" fontSize:20];26         label.color = ccYELLOW;27         label.position = CGPointMake(size.width * 0.5f, size.height * 0.4f);28         [self addChild:label]; 29         [self setTouchEnabled:YES];30     }  31     return self;32 }
Scene1.m

 

二、进度显示(针对中间场景)

有了中间场景的方法了,那么直接把进度条加到中间场景里面就ok了么。

但是如果仔细观察切换场景的过程,会发现loadingScene的帧率是不动的,这意味着在切换场景的过程中loadingScene是不刷新的。无论你如何修改进度条的百分比,loadingScene还是保持在切换scene2前的状态,直到进入scene2而loadingScene释放。

待续

 

转载于:https://www.cnblogs.com/creeper/p/3303772.html

你可能感兴趣的文章
前端JS利用canvas的drawImage()对图片进行压缩
查看>>
一键切换皮肤的解决思想及iframe嵌套时寻找下级iframe的方法
查看>>
van-dialog 组件调用 报错
查看>>
VC++中的__super::
查看>>
DS1-14
查看>>
c# Mongodb两个字段不相等 MongoDB原生查询
查看>>
排序算法-冒泡排序
查看>>
finally 的作用是什么?
查看>>
嵌入式Linux的调试技术
查看>>
CSS3
查看>>
用友U9 基础使用文件所在目录
查看>>
iOS CALayer 学习(1)
查看>>
jquery 分页控件(一)
查看>>
StackAndQueue(栈与队列)
查看>>
大话数据结构之一(绪论、算法)
查看>>
[转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
查看>>
天涯宝盒-天涯看贴脚本-只看楼主-自动翻页
查看>>
实战MEF(5):导出元数据
查看>>
python中获取文件目录的方法
查看>>
南阳oj 分数加减法
查看>>