游戏中需要全局管理很多的资源,如图片、音频文件等。下面我们设计一个骨骼资源管理类,名叫:AtlasLoader,设计为全局共享类,用于载入资源和通过资源名称获取精灵帧。
下面先上头文件:
#ifndef __EngryBird__AtlasLoader__#define __EngryBird__AtlasLoader__#include "cocos2d.h"/** * The struct of the atlas file */typedef struct tag_atlas { char name[255]; // the image's name int wIDth; // the image's wIDth int height; // the image's height cocos2d::Vec2 startposition; // the image's start position cocos2d::Vec2 endposition; // the image's end position} Atlas;/** * The hepler class for loading the resources of atlas.png/atlas.txt * * @Note This is a global shared class,just call the getInstance class method * to get the object */class AtlasLoader {public: /** * Get the instance of AtlasLoader */ static AtlasLoader* getInstance(); /** * Destroy the instance of AtlasLoader,and will free all memory it takes */ static voID destroy(); /** * Load with file name of an atlas and default load the atlas.png to texture * * @param filename the name of an atlas file * * @note This function load the images sync,so it will delay the main thread. * You can call like that: AtlasLoader::getInstance()->loadAtlas("filename"); */ voID loadAtlas(std::string filename); /** * Load with file name of an atlas * * @param filename the name of an atlas file * @param texture the Texture2D object,using to create a sprite frame * * This function load the images sync,so it will delay the main thread. * You can call like that: AtlasLoader::getInstance()->loadAtlas("filename",texture); */ voID loadAtlas(std::string filename,cocos2d::Texture2D *texture); /** * Get the sprite frame with an image name * * @param imagename the name of image * * @return the sprite frame object related to an image */ cocos2d::SpriteFrame* getSpriteFrame(std::string imagename);protected: /** * The default constructor */ AtlasLoader(); /** * Initializes the instance of AtlasLoader * * @note When you are porting Cocos2d-x to a new platform,you may need to take care of * this method. * * @return true if succeeded,otherwise false */ virtual bool init();private: /** * The singleton pointer of AtlasLoader */ static AtlasLoader* s_sharedAtlasLoader; /** * The container to store all the sprite frames that has already loaded */ cocos2d::Map<std::string,cocos2d::SpriteFrame*> _spriteFrames;};#endif /* defined(__EngryBird__AtlasLoader__) */
声明了Atlas枚举,与atlas.txt文件中每一行结构是一一对应的。
骨骼文件中,会记录着精灵的图片名称、宽度、高度、起始位置和终止位置,这样就可以通过读取文件来获取精灵应该放置在哪里了。
此类为人全局共享的,因此必须通过下面的方法来创建或获取:
/** * Get the instance of AtlasLoader */ static AtlasLoader* getInstance();
我们在编码的时候,尽量与cocos2dx引擎的代码风格一致,这样更易于阅读。静态方法是类方法,不是某个对象的方法,这样就是共享的了。
接下来是实现文件。
关于怎么写单例,这里只说一遍,后面的文章中不会重复再说明,因为写法是一样的,只是名称变了而已。
// Initializes the shared object to be nullptrAtlasLoader* AtlasLoader::s_sharedAtlasLoader = NulL;AtlasLoader* AtlasLoader::getInstance() { if (s_sharedAtlasLoader == NulL) { s_sharedAtlasLoader = new AtlasLoader(); if (!s_sharedAtlasLoader->init()) { delete s_sharedAtlasLoader; s_sharedAtlasLoader = NulL; cclOG("Error: Could not init s_sharedAtlasLoader object"); } } return s_sharedAtlasLoader;}
静态成员变量s_sharedAtlasLoader不能放在构造函数中初始化,所以需要在全局中初始化。
下面是getInstance方法的实现,这里通过判断全局共享变量是否为NulL,如果为NulL表示没有创建过,则创建之,否则不再创建,而是直接使用。这就是所谓的单例。当创建失败时,就把资源给释放掉了。
注意:这里是没有考虑线程安全的,在iOS中,我们写单例都会考虑到线程的安全问题。
下面说说加载资源最重要的方法:
voID AtlasLoader::loadAtlas(std::string filename,cocos2d::Texture2D *texture) {// 这里通过文件 *** 作,读取文件,如atlas.txt文件// fileUtils是一个文件 *** 作辅助类,是引擎自带的类,获取的是字符串 std::string data = fileUtils::getInstance()->getStringFromfile(filename); // 这里是通过分割读取行,一行一行的读取后(换行符是分割符),把对应的字段写入到Atlas结构中,然后获取精灵在骨骼中的区域,就可以获取到精灵帧了,并放到_spriteFrames中,这个是一个Map类型对象,可通过精灵的名称(key)来获取到精灵帧(value) size_t pos = data.find_first_of("\n"); std::string line = data.substr(0,pos); data = data.substr(pos + 1); Atlas atlas; while (line.length() > 0) { sscanf(line.c_str(),"%s %d %d %f %f %f %f",atlas.name,&atlas.wIDth,&atlas.height,&atlas.startposition.x,&atlas.startposition.y,&atlas.endposition.x,&atlas.endposition.y); atlas.startposition.x *= 1024; atlas.startposition.y *= 1024; atlas.endposition.x *= 1024; atlas.endposition.y *= 1024; // 读取下一行 pos = data.find_first_of("\n"); line = data.substr(0,pos); data = data.substr(pos + 1); // fix 1px edge BUG if (atlas.name == std::string("land")) { ++atlas.startposition.x; } // use the data to create a sprite frame Rect rect = Rect(atlas.startposition.x,atlas.startposition.y,atlas.wIDth,atlas.height); auto spriteFrame = SpriteFrame::createWithTexture(texture,rect); _spriteFrames.insert(std::string(atlas.name),spriteFrame); }}
好了,这个类已经说得很明白了吧,如果还有不明白的地方,可以联系我哦!!!!
下一步,说说这个屏幕适配的问题
总结以上是内存溢出为你收集整理的cocos2dx3.3开发FlappyBird总结四:资源管理类全部内容,希望文章能够帮你解决cocos2dx3.3开发FlappyBird总结四:资源管理类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)