原始文章地址:http://www.jb51.cc/article/p-zqlfzpgw-bbv.html
// 通过plist载入缓存@H_301_5@
CCSpriteFrameCache::sharedSpriteFrameCache@H_301_5@()->@H_301_5@addSpriteFramesWithFile("test.plist"@H_301_5@);
// 通过缓存载入sprite@H_301_5@
CCSprite*@H_301_5@ sp =@H_301_5@ CCSprite::createWithSpriteFrameName@H_301_5@("test01.png"@H_301_5@);
以上2句代码,可以通过plist创建一个sprite,简单分析下过程。
通过plist载入缓存
首先是通过plist载入缓存,跟踪到源码看到如下片段:
void@H_301_5@ CCSpriteFrameCache::addSpriteFramesWithFile@H_301_5@(const char *@H_301_5@pszPlist)
{
CCAssert(pszPlist,"plist filename should not be NULL"@H_301_5@);
// 判断是否加载过该文件 如果没加载过,才做以下这些事情@H_301_5@
if@H_301_5@ (m_pLoadedFileNames->@H_301_5@find(pszPlist) ==@H_301_5@ m_pLoadedFileNames->@H_301_5@end())
{
// 获取完整路径名,创建dict@H_301_5@
std::string@H_301_5@ fullPath =@H_301_5@ CCFileUtils::sharedFileUtils@H_301_5@()->@H_301_5@fullPathForFilename(pszPlist);
CCDictionary *@H_301_5@dict =@H_301_5@ CCDictionary::createWithContentsOfFileThreadSafe@H_301_5@(fullPath.@H_301_5@c_str());
string@H_301_5@ texturePath(""@H_301_5@);
// 尝试获取textureFileName,如果需要指定,格式大概长这样:@H_301_5@
// <key>Metadata</key>@H_301_5@
// <dict>@H_301_5@
// <key>textureFileName</key>@H_301_5@
// <string>tex.png</string>@H_301_5@
// </dictt>@H_301_5@
// 指定载入tex.png@H_301_5@
CCDictionary*@H_301_5@ MetadataDict =@H_301_5@ (CCDictionary*@H_301_5@)dict->@H_301_5@objectForKey("Metadata"@H_301_5@);
if@H_301_5@ (MetadataDict)
{
// try to read texture file name from Meta data@H_301_5@
texturePath =@H_301_5@ MetadataDict->@H_301_5@valueForKey("textureFileName"@H_301_5@)->@H_301_5@getCString();
}
// 如果有指定tex文件,则直接查找完整路径@H_301_5@
if@H_301_5@ (!@H_301_5@ texturePath.@H_301_5@empty())
{
// build texture path relative to plist file@H_301_5@
texturePath =@H_301_5@ CCFileUtils::sharedFileUtils@H_301_5@()->@H_301_5@fullPathFromRelativeFile(texturePath.@H_301_5@c_str(),pszPlist);
}
else@H_301_5@ // 没有指定tex文件,载入plist对应的png,比如plist文件名:abc.plist,则载入的png为:abc.png@H_301_5@
{
// build texture path by replacing file extension@H_301_5@
texturePath =@H_301_5@ pszPlist;
// remove .xxx@H_301_5@
size_t startPos =@H_301_5@ texturePath.@H_301_5@find_last_of("."@H_301_5@);
texturePath =@H_301_5@ texturePath.@H_301_5@erase(startPos);
// append .png@H_301_5@
texturePath =@H_301_5@ texturePath.@H_301_5@append(".png"@H_301_5@);
CCLOG("cocos2d: CCSpriteFrameCache: Trying to use file %s as texture"@H_301_5@,texturePath.@H_301_5@c_str());
}
// 载入图片@H_301_5@
CCTexture2D *@H_301_5@pTexture =@H_301_5@ CCTextureCache::sharedTextureCache@H_301_5@()->@H_301_5@addImage(texturePath.@H_301_5@c_str());
if@H_301_5@ (pTexture)
{
// 载入spriteFrames@H_301_5@
addSpriteFramesWithDictionary(dict,pTexture);
m_pLoadedFileNames->@H_301_5@insert(pszPlist);
}
else@H_301_5@
{
CCLOG("cocos2d: CCSpriteFrameCache: Couldn't load texture"@H_301_5@);
}
dict->@H_301_5@release();
}
}
然后到了这里:
void CCSpriteFrameCache::addSpriteFramesWithDictionary(CCDictionary* dictionary,CCTexture2D *pobTexture)
{
/*
// format 4种格式支持
Supported Zwoptex Formats:
ZWTCoordinatesFormatOptionXMLLegacy = 0,// Flash Version ZWTCoordinatesFormatOptionXML1_0 = 1,// Desktop Version 0.0 - 0.4b ZWTCoordinatesFormatOptionXML1_1 = 2,// Desktop Version 1.0.0 - 1.0.1 ZWTCoordinatesFormatOptionXML1_2 = 3,// Desktop Version 1.0.2+ */ // 分离2个dict CCDictionary *MetadataDict = (CCDictionary*)dictionary->objectForKey("Metadata"); CCDictionary *framesDict = (CCDictionary*)dictionary->objectForKey("frames"); int format = 0; // 从Metadata获取格式 默认为0 if(MetadataDict != NULL) { format = MetadataDict->valueForKey("format")->intValue(); } // 检测format 支持0-3 CCAssert(format >=0 && format <= 3,"format is not supported for CCSpriteFrameCache addSpriteFramesWithDictionary:textureFilename:"); // 遍历frames CCDictElement* pElement = NULL; CCDICT_FOREACH(framesDict,pElement) { CCDictionary* frameDict = (CCDictionary*)pElement->getObject(); std::string spriteFrameName = pElement->getStrKey(); // 取key作为sprite名 // 如果已经加载过 不再处理 CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName); if (spriteFrame) { continue; } // 根据format处理 if(format == 0) { float x = frameDict->valueForKey("x")->floatValue(); float y = frameDict->valueForKey("y")->floatValue(); float w = frameDict->valueForKey("width")->floatValue(); float h = frameDict->valueForKey("height")->floatValue(); float ox = frameDict->valueForKey("offsetX")->floatValue(); float oy = frameDict->valueForKey("offsetY")->floatValue(); int ow = frameDict->valueForKey("originalWidth")->intValue(); int oh = frameDict->valueForKey("originalHeight")->intValue(); // check ow/oh if(!ow || !oh) { CCLOGWARN("cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenrate the .plist"); } // abs ow/oh ow = abs(ow); oh = abs(oh); // create frame spriteFrame = new CCSpriteFrame(); // 对照一下,大概就明白了 // initWithTexture(CCTexture2D* pobTexture,const CCRect& rect,bool rotated,const CCPoint& offset,const CCSize& originalSize) spriteFrame->initWithTexture(pobTexture,CCRectMake(x,y,w,h),false,CCPointMake(ox,oy),CCSizeMake((float)ow,(float)oh) ); } ...// 以下类似 // 加入缓存,名字用spriteFrameName <span style="font-family: Arial,Helvetica,sans-serif;"> m_pSpriteFrames是一个dict</span> m_pSpriteFrames->setObject(spriteFrame,spriteFrameName); spriteFrame->release(); }
}
于是,这部分的大概流程就是:
载入plist,载入texture,根据plist选择texture的区域,载入spriteFrame,加入到缓存。
通过缓存载入sprite
CCSprite* CCSprite::createWithSpriteFrameName(const@H_301_5@ char@H_301_5@ *pszSpriteFrameName)
{
// 从缓存里取对应名字的spriteFrame@H_301_5@
CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(pszSpriteFrameName);
#if@H_301_5@ COCOS2D_DEBUG > 0@H_301_5@
char@H_301_5@ msg[256@H_301_5@] = {0@H_301_5@};
sprintf(msg,"Invalid spriteFrameName: %s"@H_301_5@,pszSpriteFrameName);
CCAssert(pFrame != NULL,msg);
#endif@H_301_5@@H_301_5@
return@H_301_5@ createWithSpriteFrame(pFrame);
}