cocos2dx资源加载机制(同步/异步)

首先cocos2dx里的资源,有png,plist(pvr),exportjson(json)大致这三类,我们也从这3类去研究相应的加载代码。

本次代码分析基于:

cocos2dx3.2

1、png

png格式的资源,从sprite作为一个切入口来分析,一般Sprite的创建如下

Sprite* Sprite::create(const std::string& filename)

参数filename,是图片资源的路径。

内部调用的initWithFile

Sprite *sprite = new (std::nothrow) Sprite();if (sprite && sprite->initWithFile(filename)){sprite->autorelease();return sprite;}

在initWithFile方法里

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);if (texture){Rect rect = Rect::ZERO;rect.size = texture->getContentSize();return initWithTexture(texture, rect);}

在Texture2D * TextureCache::addImage(const std::string &path)方法是实际的载入资源的实现

// 将相对路径转换成绝对路径std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path);    if (fullpath.size() == 0)    {        return nullptr;    }// 查找是否已经载入过,找到老资源,直接返回    auto it = _textures.find(fullpath);    if( it != _textures.end() )        texture = it->second;

有传入的相对路径换成了绝对路径,其在找资源时,会搜索以下函数设置的搜索路径

void FileUtils::setSearchPaths(const std::vector<std::string>& searchPaths)

bool bRet = image->initWithImageFile(fullpath);CC_BREAK_IF(!bRet);texture = new Texture2D();if( texture && texture->initWithImage(image) ){#if CC_ENABLE_CACHE_TEXTURE_DATA// cache the texture file nameVolatileTextureMgr::addImageTexture(texture, fullpath);#endif// texture already retained, no need to re-retain it_textures.insert( std::make_pair(fullpath, texture) );

没有找到,构造出Texture,然后按<fullpath,texture>放入_textures。以备下次下次资源载入时查找使用,

结论是:png这种资源是 资源的完全路径用来查找相应资源的。

2、plist 格式资源的载入方式

a.最原始的调用方式

void addSpriteFramesWithFile(const std::string& plist);

b.重载方式

void addSpriteFramesWithFile(const std::string&plist, Texture2D *texture);

void addSpriteFramesWithFile(const std::string& plist, const std::string& textureFileName);

void addSpriteFramesWithFile(const std::string& plist)分析如下,

// 这里做了一下cached,提高效率if (_loadedFileNames->find(plist) == _loadedFileNames->end()){// 转换成全路径,同理会在搜索路径里搜索std::string fullPath = FileUtils::getInstance()->fullPathForFilename(plist);// 解析plist,返回ValueMapValueMap dict = FileUtils::getInstance()->getValueMapFromFile(fullPath);string texturePath("");// 图片资源在plist里的metadata/textureFileNameif (dict.find("metadata") != dict.end()){ValueMap& metadataDict = dict["metadata"].asValueMap();// try to read texture file name from meta datatexturePath = metadataDict["textureFileName"].asString();}// 因为plist里的图片资源都是文件名,而plist一般是一个相对路径,拼接一下if (!texturePath.empty()){// build texture path relative to plist filetexturePath = FileUtils::getInstance()->fullPathFromRelativeFile(texturePath.c_str(), plist);}else{// 要是plist里没有找到metadata/textureFileName,直接就是plist去后缀,该成plist的路径+.png// build texture path by replacing file extensiontexturePath = plist;// remove .xxxsize_t startPos = texturePath.find_last_of(".");texturePath = texturePath.erase(startPos);// append .pngtexturePath = texturePath.append(".png");CCLOG("cocos2d: SpriteFrameCache: Trying to use file %s as texture", texturePath.c_str());}// 熟悉的方法又来了,参考png格式资源载入的分析吧Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(texturePath.c_str());if (texture){// 做一下善后的初始化工作addSpriteFramesWithDictionary(dict, texture); <span style="white-space:pre"></span>// 开头怎么cached检查的,最后把自己也加入吧_loadedFileNames->insert(plist);}else{CCLOG("cocos2d: SpriteFrameCache: Couldn't load texture");}}

基本分都写在代码注释里了,其实plist格式资源,图片相关资源还是最后调用的

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(texturePath.c_str());

也是plist的图片资源,被便签为:plist的全路径改后缀为.png,但是plist里有很多子块SpriteFrame,那么这些小图块是怎么组织安排的,,这些小SpriteFrame是在

void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Texture2D* texture)

中处理的,

『 不可能 』只存在於蠢人的字典里

cocos2dx资源加载机制(同步/异步)

相关文章:

你感兴趣的文章:

标签云: