?
当前位置:??操作系统>IOS

cocos2d中CCSpriteFrameCache文件同时存在两个plist的问题解决

?
分享到:
????发布时间:2014-1-17??


????本文导语:? cocos2d是一个基于MIT协议的开源框架,用于构建游戏、应用程序和其他图形界面交互应用。可以让你在创建自己的多平台游戏时节省很多的时间。Cocos2D也拥有几个主要版本,包括Cocos2D-iPhone、Cocos2D-X,以及被社区普遍看好...

? cocos2d是一个基于MIT协议开源框架,用于构建游戏、应用程序和其他图形界面交互应用。可以让你在创建自己多平台游戏时节省很多的时间

cocos2d也拥有几个主要版本,包括cocos2d-iphonecocos2d-x,以及被社区普遍看好的cocos2d-html5JavaScript bindings for Cocos2D-X。同时也拥有了非常优秀的编辑器(独立编辑器),例如SpriteSheet Editors、Particle Editors 、Font Editors 、 Tilemap Editors。另外,2012年发布的CocoStudio工具集是开源游戏引擎Cocos2d-x开发团队官方推出的游戏开发工具,目前已经进入稳定版。CocoStudio吸取了他们自己在游戏制作中的经验,为移动游戏开发者和团队量身定做,旨在降低游戏开发的门槛,提高开发效率,同时也为Cocos2D-X的进一步发展打下基础。

? ? 最近在做一项工作,将基于cocos2d-iphone游戏转换跨平台版本。

? ? 以下为OC代码:

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"game_ui.plist"]; [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"game_effect.plist"];

以下为Lua代码(我们的UI采用Lua编码):

display.addSpriteFramesWithFile('game_ui.plist') display.addSpriteFramesWithFile('game_effect.plist')

运行时,却发现了在OC版本中没有出现的异常CCSprite is not using the same texture id”

跟踪该png文件,却发现health_bar.png文件同时存在于这两个plist

这时候就产生疑问了,oc和c++版本的资源文件都是一样的。为什么cocos2d-x就会报异常呢?

好在cocos2d是开源的,所以开始研究addSpriteFramesWithFile的实现细节

cocos2d-iphone

-(void) addSpriteFramesWithFile:(NSString*)plist { NSAssert(plist, @"plist filename should not be nil"); if( ! [_loadedFilenames member:plist] ) { NSString *path = [[CCFileUtils sharedFileUtils] fullPathForFilename:plist]; NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; NSString *texturePath = nil; NSDictionary *metadataDict = [dict objectForKey:@"metadata"]; if( metadataDict ) // try to read ?texture file name from meta data texturePath = [metadataDict objectForKey:@"textureFileName"]; if( texturePath ) { // build texture path relative to plist file NSString *textureBase = [plist stringByDeletingLastPathComponent]; texturePath = [textureBase stringByAppendingPathComponent:texturePath]; } else { // build texture path by replacing file extension texturePath = [plist stringByDeletingPathExtension]; texturePath = [texturePath stringByAppendingPathExtension:@"png"]; CCLOG(@"cocos2d: CCSpriteFrameCache: Trying to use file '%@' as texture", texturePath); } [self addSpriteFramesWithDictionary:dict textureFilename:texturePath]; [_loadedFilenames addObject:plist]; } else CCLOGINFO(@"cocos2d: CCSpriteFrameCache: file already loaded: %@", plist); }


cocos2d-x

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 <= pelement="NULL;" framedict="(CCDictionary*)pElement-">getObject(); ? ? ? ?std::string spriteFrameName = pElement->getStrKey(); ? ? ? ?CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName); ? ? ? ?if (spriteFrame) ? ? ? ?{ ? ? ? ? ? ?continue; ? ? ? ?} ? ? ? ? ? ? ? ?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(); ? ?}}void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist, CCTexture2D *pobTexture){ ? ?std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(pszPlist); ? ?CCDictionary *dict = CCDictionary::createWithContentsOfFileThreadSafe(fullPath.c_str()); ? ?addSpriteFramesWithDictionary(dict, pobTexture); ? ?dict->release();}


? cocos2d-x比cocos2d-iphone多做了一步校验

? ? ? ?CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName); ? ? ? ?if (spriteFrame) ? ? ? ?{ ? ? ? ? ? ?continue; ? ? ? ?}


然后,我将c++版本的plist加载顺序调整一下。一个png就不应该同时添加到两个plist中。


    您可能感兴趣的文章:

相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

?2012-2019,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号