cocos2d-x 场景切换

本文转自:http://blog.sina.com.cn/s/blog_c5102aa30101js0o.html

目前的理解。。不对的地方希望大家指正。

以后实践中再体会。。。。。。。。。。。

场景切换是最容易出问题的地方。

网上有种说法是:

场景切换时在旧场景中把新场景需要的图片资源先加载到全局的纹理缓存区。加载时在旧的场景上显示进度条。加载完毕进入新场景。



(以下是对比在旧场景中加载新场景图片资源和在新场景自己中加载图片资源区别。)

场景A,新图片(全局缓存区)+LOADINGSCENE+场景B

场景A+LOADINGSCENE+场景B+新图片(全局缓存区)。

稍微有些差别。

结合使用中间场景我想这样做会更好点。



中间场景一个就够了。他就一个枚举值标识目标场景。最好不要让他干别的。本来就不想它占太多内存。



场景切换时,使用LAODINSCENE这个中间场景。新的场景中的INIT方法去加载本场景需要的一些图片资源到全局的纹理缓存区。加载时用一个层显示进度条。图片全部加载完毕,移除这个显示进度条的层。然后创建其他需要的层。如果其他层很耗内存的话还可以延时个一两帧(或者在上一个场景的析构函数调用完之后新场景的onenter,onenterdidfinish中去做其他的。)。用了中间场景之后。应该就没必要了。。



实践中得到的结果是:

@1:不加切换效果时:

B->gouzao

B->init  如果场景中各层节点及其子节点很占内存,那么可以几帧之后再创建其他层。

Init中加载一些必要的东西。

A->onExit

A->xigou

B->onEnter  在这里创建其他层也挺靠谱。因为场景A已经析构了。

B->onEnterTransitionDidFinish

@2:加切换效果时:切换效果不是中间场景。

B->gouzao

B->init

B->onEnter

即便等待几帧再去创建场景的层,还是会在这个位置。依然在A场景析构前。尽量不用过渡效果。B场景的update调用了好几次了,A场景才调用自己的onExit。。。

A->onExit

B->onEnterTranstionDidFinish

A->xigou

做一个笔记。。以后遇到场景切换时出问题。可以从这些方法的调用顺序中去找解决办法。



缓存释放

如果游戏有很多场景,在切换场景的时候可以把前一个场景的内存全部释放,防止总内存过高.

场景自己的内存不用担心。但是场景需要用到的加载在全局纹理缓存区的内存需要去管理。

CCTextureCache::sharedTextureCache()->removeAllTextures(); 释放到目前为止所有加载的图片

CCTextureCache::sharedTextureCache()->removeUnusedTextures(); 将引用计数为1的图片释放掉

即这个纹理没有场景使用他,只有全局的纹理缓存retain了一份。

Removes unused textures Textures that have a retain count of 1 will be deleted It is convenient to call this method after when starting a new Scene.

VS监控内存使用率???这个环境不熟。。以后再做实验。

CCTextureCache::sharedTextureCache()->removeTexture(); 单独释放某个图片

void removeTextureForKey(const char * textureKeyName)?????key是什么??

CCSpriteFrameCache(从精灵表plist文件加载) 与 CCTextureCache 释放的方法差不多。

值得注意的是释放的时机,一般在切换场景的时候释放资源,如果从A场景切换到B场景,调用的函数顺序为B::init()---->A::exit()---->B::onEnter() 可如果使用了切换效果,比如CCTransitionJumpZoom::transitionWithDuration这样的函数,则函数的调用顺序变为B::init()---->B::onEnter()---->A::exit() 而且第二种方式会有一瞬间将两个场景的资源叠加在一起,如果不采取过度,很可能会因为内存吃紧而崩溃。(返回到上面,A场景析构之后,使用removeUnusedTextures())。

有时强制释放全部资源时,会使某个正在执行的动画失去引用而弹出异常,可以调用CCActionManager::sharedManager()->removeAllActions();来解决。

先留着。。



Push,pop

Push新场景进去后,旧的场景的UPDATE停止调用。新场景被POP之后,旧场景的UPDATE恢复继续调用。内存中的相关成员变量值不变。

被POP的场景会从内存释放。。。。先调用ONEXIT。再调用析构函数。。。





onEnter,onExit这些函数在重写他们时必须调用父类实现。









1.   CCTextureCache::sharedTextureCache()->addImageAsync("img/bg.png", this, callfuncO_selector(HelloWorld::loadingCallBack)); 

2.          CCTextureCache::sharedTextureCache()->addImageAsync("img/01.png", this, callfuncO_selector(HelloWorld::loadingCallBack)); 

3.  CCSprite *s1 = CCSprite::create("img/01.png"); 

4.      CCSprite *s2 = CCSprite::create("img/02.png"); 

这样,创建精灵时不会再去加载了吧?前面场景切换时先加载一些必要的图片资源到全局的缓存区。用时,不用加载,减少IO消耗。







cocos2d-x场景切换时内存过高导致crash 解决方法

http://blog.csdn.net/zhangjingyangguang/article/details/7618048

这个帖子是别人的一些经验总结。以后实践中如果出了什么问题可以参考。

猜你喜欢

转载自xiaopao.iteye.com/blog/1990000