最近在做一项工作,将基于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 <= 3, "format is not supported for CCSpriteFrameCache addSpriteFramesWithDictionary:textureFilename:"); CCDictElement* pElement = NULL; CCDICT_FOREACH(framesDict, pElement) { CCDictionary* 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(); }
OK!事情明了了。cocos2d-x比cocos2d-iphone多做了一步校验。
CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName); if (spriteFrame) { continue; }
然后,我将c++版本的plist加载顺序调整一下。搞定。
多说一句,一个png就不应该同时添加到两个plist中。
相关推荐
该文件是iOS开发plist文件,下载可以直接使用,为iOS开发
plist文件编辑器 绿色免安装版本,解压后即可使用,汉化版本, 方便快捷可用于与.plist文件的查看
城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件城市Plist文件
在iOS开发中如何创建plist文件,如何读取出来
iOS 2016年最新的省市区plist文件
三级联动城市 plist 文件
在cocos2dx4.0中应该如何设计和读取plist文件内容。 plist文件的规定规范等。 在cocos2dx4.0中应该如何设计和读取plist文件内容。 plist文件的规定规范等。 在cocos2dx4.0中应该如何设计和读取plist文件内容。 plist...
读写plist文件,方便iOS开发读写plist文件,方便iOS开发
读取plist文件切割图集,用于cocos等工具生成的图集。
plist文件是标准的xml文件 A).写入plist文件:(Dictionary/Array) NSMutableDictionary* dict = [ [ NSMutableDictionary alloc ] initWithContentsOfFile:@"/Sample.plist" ]; [ dict setObject:@"Yes" forKey:@...
unpack_plist.exe,plist...本程序可以把一个plist文件中包含的所有图片全部解包出来。 程序基于Python3.7.2(目前最新版),Pillow==5.3.0,PyQt5==5.11.3开发 可百度COCO56到我博客免费下载,当然有能力也可以支持下 ...
plist文件解析CutPNG 一款解析 plist文件的工具 .plist ) 文件格式是一种简单的序列化格式,它支持一些基本对象类型
最新最全的中国省市区行政区划plist文件,ios开发好帮手。
plist文件加密方法
对plist 属性文件的操作 里面含两种读取 一种是沙盒里的文件 一种的程序资源里的文件
全国省市区(县)plist文件,里面的plist数据非常全面。
根据plist文件还原小图片
实现读取一个plist文件中的数据,并将其排序,最后将排序后的数据生成词典,保存至document文件