该博客为原创博客,转载请保留原始地址:http://blog.csdn.net/kantian_/article/details/21184609
游戏中什么最占用内存,毋庸置疑绝对是纹理,用mac开发的同学如果有洁癖一定用过Xcode自带的内存分析工具,你可以发现大部分内存里面存的都是纹理(简单理解就是图片啦)。如果为了减少内存使用而增加加载次数势必会令游戏不流畅,如果一次性加载很多纹理又会消耗掉更多内存,所以内存的载入时间和量都是非常值得研究的一个事情。限于笔者水平限制以及该游戏的简单性,这里其实只是冰山一角。回到这个游戏,该游戏所用到的素材不多,一张1024x1024的大图可以容纳下所有的素材还有的多,所以这里我们可以在游戏一开始全部载入。
载入的资源包括图片素材的载入和音乐素材的载入。图片的载入一定是一个异步操作,cocos2dx本身就提供了一个异步载入纹理的接口:
// start ansyc method load the atlas.png Director::getInstance()->getTextureCache()->addImageAsync("atlas.png",CC_CALLBACK_1(LoadingScene::loadingCallBack,this));
TextureCache这个类里面的addImageAsync的方法便是一个异步加载图片纹理的方法,第一个参数是图片的名字(你放在Resource里面的图片),第二个参数便是图片异步加载完成之后需要调用的回调函数,回调函数包含了加载完成之后的纹理对象。
addImageAsync:
/* Returns a Texture2D object given a file image * If the file image was notpreviously loaded, it will create a new Texture2D object and it will return it. * Otherwise it will load atexture in a new thread, and when the image is loaded, the callback will becalled with the Texture2D as a parameter. * The callback will be calledfrom the main thread, so it is safe to create any cocos2d object from thecallback. * Supported image extensions:.png, .jpg * @since v0.8 */ virtualvoidaddImageAsync(conststd::string&filepath,std::function<void(Texture2D*)>callback);
回调函数:
voidLoadingScene::loadingCallBack(Texture2D*texture){ AtlasLoader::getInstance()->loadAtlas("atlas.txt",texture); // After loading the texture ,preload all the sound SimpleAudioEngine::getInstance()->preloadEffect("sfx_die.ogg"); SimpleAudioEngine::getInstance()->preloadEffect("sfx_hit.ogg"); SimpleAudioEngine::getInstance()->preloadEffect("sfx_point.ogg"); SimpleAudioEngine::getInstance()->preloadEffect("sfx_swooshing.ogg"); SimpleAudioEngine::getInstance()->preloadEffect("sfx_wing.ogg"); // After load all the things, changethe scene to new one //auto scene =HelloWorld::createScene(); autoscene=WelcomeScene::create(); TransitionScene*transition=TransitionFade::create(1,scene); Director::getInstance()->replaceScene(transition); }
纹理载入完成之后我们就需要用纹理来形成精灵来缓存起来方便以后使用,因为来自原版游戏的素材并不是用plist来打包精灵的,所以这里就用不了SpriteFrameCache类提供的接口来对打包的纹理进行处理,所以这里我仿照SpriteFrameCache类写了一个AtlasLoader来对打包完成纹理进行解析,关于这个类,第一节已经讲过了。完成了图片纹理的载入接下来就需要对游戏音效就行预载入,不过可惜的是cocos2dx并咩有提供音效文件的异步载入方法,不过该游戏中用到的音效都很小,而且载入界面的显示的也是一张静态图,所以这里就算阻塞了主线程也没有太大关系,所以这里就直接载入了。如果你的游戏中需要载入大量的很大的音乐文件,那么可能就需要你自己写一个异步载入的方法了,官方有一个多线程的解决方案,需要的同学可以参考下官网,不过这里应该是平台强相关的。最后全部都完成之后就只需要跳转的接下去的场景便完成了游戏素材的加载。之后取精灵只需要获取AtlasLoader的单例实体便可以获取精灵了
auto sprite = AtlasLoader::getInstance()->getSpriteFrameByName(“spritename”)
具体代码以及游戏截屏还有游戏请移步该游戏在代码仓库:http://oiteboys.github.io/Earlybird/