CCSpriteFrameCache精灵帧缓存分析(1)

来源:互联网 发布:php为什么比aps.net好 编辑:程序博客网 时间:2024/06/06 16:34
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();    }}

0 0
原创粉丝点击