CCSpriteFrameCache精灵帧缓存分析(1):
1、单例类
CCSpriteFrameCache* CCSpriteFrameCache::sharedSpriteFrameCache(void)
{
if (! pSharedSpriteFrameCache)
{
pSharedSpriteFrameCache = new CCSpriteFrameCache();
pSharedSpriteFrameCache->init();
}
return pSharedSpriteFrameCache;
}
2、常用方法分析:
void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist)
{
CCAssert(pszPlist, "plist filename should not be NULL");
//文件缓存m_pLoadedFileNames,如果已经加载过,则不再加载
if (m_pLoadedFileNames->find(pszPlist) == m_pLoadedFileNames->end())
{
std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(pszPlist);
//因为xx.plist文件的根节点<dict>,所以使用createWithContentsOfFileThreadSafe方法
//进行解析
CCDictionary *dict = CCDictionary::createWithContentsOfFileThreadSafe(fullPath.c_str());
string texturePath("");
/*
<key>metadata</key>
<dict>
<key>format</key>
<integer>2</integer>
<key>realTextureFileName</key>
<string>digit03.pvr.ccz</string>
<key>size</key>
<string>{128,256}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:3c8e7a7da2ef2a8189712fc559ff0750:163e3804f74ef566f6194c8708efc6b9:d14ec1949f1c567f2820ca7d65c7607d$</string>
<key>textureFileName</key>
<string>digit03.pvr.ccz</string>
</dict>
*/
CCDictionary* metadataDict = (CCDictionary*)dict->objectForKey("metadata");
if (metadataDict)
{
// try to read texture file name from meta data
// 得到纹理图片名
texturePath = metadataDict->valueForKey("textureFileName")->getCString();
}
if (! texturePath.empty())
{
// build texture path relative to plist file
// texturePath 如果纹理名不为空,则通过pszPlist文件的相对路径,获得纹理文件的全路径
texturePath = CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile(texturePath.c_str(), pszPlist);
}
else
{
//如果texturePath为空,则把pszPlist的后缀替换成.png,作为纹理图片名
// build texture path by replacing file extension
texturePath = pszPlist;
// remove .xxx
size_t startPos = texturePath.find_last_of(".");
texturePath = texturePath.erase(startPos);
// append .png
texturePath = texturePath.append(".png");
CCLOG("cocos2d: CCSpriteFrameCache: Trying to use file %s as texture", texturePath.c_str());
}
//加载纹理
CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(texturePath.c_str());
if (pTexture)
{
addSpriteFramesWithDictionary(dict, pTexture);
m_pLoadedFileNames->insert(pszPlist);
}
else
{
CCLOG("cocos2d: CCSpriteFrameCache: Couldn't load texture");
}
dict->release();
}
}
---addSpriteFramesWithDictionary-->>
void CCSpriteFrameCache::addSpriteFramesWithDictionary(CCDictionary* dictionary, CCTexture2D *pobTexture)
{
/*
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+
*/
CCDictionary *metadataDict = (CCDictionary*)dictionary->objectForKey("metadata");
//存储小图片信息的字典
CCDictionary *framesDict = (CCDictionary*)dictionary->objectForKey("frames");
int format = 0;
// get the format
// 获取图片打包的格式,版本
if(metadataDict != NULL)
{
format = metadataDict->valueForKey("format")->intValue();
}
// check the format
CCAssert(format >=0 && format <= 3, "format is not supported for CCSpriteFrameCache addSpriteFramesWithDictionary:textureFilename:");
//遍历小图片信息字典,根据小图片信息生成存储CCSpriteFrame的字典
CCDictElement* pElement = NULL;
CCDICT_FOREACH(framesDict, pElement)
{
/*
<key>digit03_00.png</key>
<dict>
<key>frame</key>
<string>{{2,70},{32,44}}</string>
<key>offset</key>
<string>{0,0}</string>
<key>rotated</key>
<true/>
<key>sourceColorRect</key>
<string>{{0,0},{32,44}}</string>
<key>sourceSize</key>
<string>{32,44}</string>
</dict>
*/
CCDictionary* frameDict = (CCDictionary*)pElement->getObject();
std::string spriteFrameName = pElement->getStrKey();
CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName);
if (spriteFrame)
{
continue;
}
//根据类型进行不同的解析,最终都会根据图片信息生成CCSpriteFrame,
//并且存放到m_pSpriteFrames缓存中,那我们在创建精灵时,就可以
//使用这些CCSpriteFrame去创建,这样就可以把很多小图打包成大图纹理,
//优化纹理的使用。
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();
spriteFrame->initWithTexture(pobTexture,
CCRectMake(x, y, w, h),
false,
CCPointMake(ox, oy),
CCSizeMake((float)ow, (float)oh)
);
}
else if(format == 1 || format == 2)
{
CCRect frame = CCRectFromString(frameDict->valueForKey("frame")->getCString());
bool rotated = false;
// rotation
if (format == 2)
{
rotated = frameDict->valueForKey("rotated")->boolValue();
}
CCPoint offset = CCPointFromString(frameDict->valueForKey("offset")->getCString());
CCSize sourceSize = CCSizeFromString(frameDict->valueForKey("sourceSize")->getCString());
// create frame
spriteFrame = new CCSpriteFrame();
spriteFrame->initWithTexture(pobTexture,
frame,
rotated,
offset,
sourceSize
);
}
else if (format == 3)
{
// get values
CCSize spriteSize = CCSizeFromString(frameDict->valueForKey("spriteSize")->getCString());
CCPoint spriteOffset = CCPointFromString(frameDict->valueForKey("spriteOffset")->getCString());
CCSize spriteSourceSize = CCSizeFromString(frameDict->valueForKey("spriteSourceSize")->getCString());
CCRect textureRect = CCRectFromString(frameDict->valueForKey("textureRect")->getCString());
bool textureRotated = frameDict->valueForKey("textureRotated")->boolValue();
// get aliases
CCArray* aliases = (CCArray*) (frameDict->objectForKey("aliases"));
CCString * frameKey = new CCString(spriteFrameName);
CCObject* pObj = NULL;
CCARRAY_FOREACH(aliases, pObj)
{
std::string oneAlias = ((CCString*)pObj)->getCString();
if (m_pSpriteFramesAliases->objectForKey(oneAlias.c_str()))
{
CCLOGWARN("cocos2d: WARNING: an alias with name %s already exists", oneAlias.c_str());
}
m_pSpriteFramesAliases->setObject(frameKey, oneAlias.c_str());
}
frameKey->release();
// create frame
spriteFrame = new CCSpriteFrame();
spriteFrame->initWithTexture(pobTexture,
CCRectMake(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
textureRotated,
spriteOffset,
spriteSourceSize);
}
// add sprite frame
m_pSpriteFrames->setObject(spriteFrame, spriteFrameName);
spriteFrame->release();
}
}
CCSpriteFrameCache精灵帧缓存分析(1)
最新推荐文章于 2018-09-07 16:21:38 发布