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

一、场景切换

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

LoadingScene.m

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

Scene1.m

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

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

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

待续

[cocos2d]场景切换以及切换进度显示的更多相关文章

  1. Unity3D 场景切换加载进度条实现

    需要三个场景,场景A,场景B,场景C: 场景A:一个按钮,点击加载场景B: 场景B:从A切换到C过度场景,加载进度条: 场景C:目标场景: 创建OnProgress.cs脚本: using Syste ...

  2. LNMP下wordpress无法切换主题,只显示当前主题解决方法

    最近在lnmp下发现wordpress后台无法切换主题,只能显示当前主题,开始还以为是文件没传完,又重置了一遍,还是一样.百度得知,原来军哥的LNMP安装包默认关闭了scandir函数,为了安全考虑. ...

  3. 解决微信小程序的wx-charts插件tab切换时的显示会出现位置移动问题-tab切换时,图表显示错乱-实现滑动tab

    解决Echarts在微信小程序tab切换时的显示会出现位置移动问题 tab切换时,图表显示错乱 <canvas class="kcanvas" canvas-id=" ...

  4. 使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态。点击列表的项,切换二级列表的显示或隐藏状态

    查看本章节 查看作业目录 需求说明: 使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态.点击列表的项,切 ...

  5. fijkplayer问题反馈:暂停时拖动进度光标,在窗口模式与全屏模式间切换后,进度光标不能及时更新、正常跟进

    fijkplayer-0.8.4很优秀,造福苍生,非常感谢! 使用fijkplayer-0.8.4开发的过程中遇到以下问题,特此记录.提交上传:https://github.com/befovy/fi ...

  6. python-web自动化-元素操作:windows窗口切换 / alert切换 / iframe切换

    1. windows窗口切换:切换到要操作的窗口 有多个窗口: 1. 触发新窗口的出现 2. 得知道新窗口是谁 -- 依据窗口的window_handle来识别窗口 3. 得到窗口的window_ha ...

  7. vue + element-ui 制作tab切换(切换vue组件,踩坑总结)

    本篇文章使用vue结合element-ui开发tab切换vue的不同组件,每一个tab切换的都是一个新的组件. 1.vue如何使用element-ui 上一篇文章已经分享了如何在vue中使用eleme ...

  8. html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器

    以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上 ...

  9. Retrofit2文件上传下载及其进度显示

    序 前面一篇文章介绍了Retrofit2的基本使用,这篇文章接着介绍使用Retrofit2实现文件上传和文件下载,以及上传下载过程中如何实现进度的显示. 文件上传 定义接口 1 2 3 @Multip ...

随机推荐

  1. C# if,ifelse语句

    1,if语句的判断是根据布尔表达式的值. if语句主要有两种方式,如下 Code(1)if(boolean) do (2)if(boolean){ do } 一般大家都是用第二种方法,因为第一种方法只 ...

  2. JS操作CSS样式

    一.样式表(css) 使用样式表可以更好的显示WEB文档,也可以结合javascript从而实现很好的控制样式表. 样式(css)与内容(html): HTML是处理文档结构的,HTML可以实现如何把 ...

  3. 自动生成get,set方法

    引发的问题: Action中有一个属性名字叫private boolean isHideNumber 用struts2的<s:if test ="isHideNumber"& ...

  4. Xamarin.iOS - 利用Settings插件与EAIntroView制作App的欢迎界面

    Xamarin.iOS - 利用Settings插件与EAIntroView制作App的欢迎界面 关于欢迎界面 很多App第一次启动都会有一个欢迎界面,欢迎界面往往决定这用户对App的第一映像,所以欢 ...

  5. linux 搭建pptpd vpn(转,备忘)

    1.第一步需要安装PPTP,以用来提供VPN服务.sudo apt-get install pptpd注:如果有问题的话比如提示找不到之类的,apt-get update 一下应该就可以了,然后再来一 ...

  6. Myeclipse下不用dom4j等解析xml文档

  7. UVA 11462 Age Sort(计数排序法 优化输入输出)

    Age Sort You are given the ages (in years) of all people of a country with at least 1 year of age. Y ...

  8. ERROR 1045 (28000): Access denied for user 'root'@'localhost'

    # /etc/init.d/mysql stop# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &# mysq ...

  9. ubuntu ll命令

    用过 Redhat 的朋友应该很熟悉 ll 这个命令,就相当于 ls -l,但在 Ubuntu 中就不行了.严格来说 ll 不是一个命令,只是命令的别名而已.很多 Linux 用户都使用 bash s ...

  10. javascript 学习笔记之模块化编程

    题外: 进行web开发3年多了,javascript(后称js)用的也比较多,但是大部分都局限于函数的层次,有些公共的js函数可重用性不好,造成了程序的大量冗余,可读性差(虽然一直保留着注释的习惯,但 ...