最近在做一项工作,将基于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中。
相关推荐
使用`CCSpriteFrameCache`的`addSpriteFramesWithFile:`方法加载`.plist`文件。 ```swift let frameCache = CCSpriteFrameCache.shared() frameCache.addSpriteFramesWithFile("background.plist") ``` 2. 创建一个`...
尽管如此,重复加载同一部分的图片不会再增加额外的内存,因为它们已经存在于内存中。 为了控制内存占用,开发者需要适时地释放缓存。在场景切换时,可以清理前一场景的资源。Cocos2d-x提供了如CCTextureCache的...
2. 获取精灵帧:通过` CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile()` 添加精灵帧信息,通常是.plist文件,它包含了精灵表的布局信息。 3. 创建动画:使用` CCArray `存储` ...
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
,,基于SMO的三相PMSM无速度传感器控制(基于反正切函数) ,核心关键词:SMO(滑模观测器); 三相PMSM(永磁同步电机); 无速度传感器控制; 反正切函数; 控制系统。,基于SMO算法的三相PMSM无速度传感器反正切函数控制
网络文化互动中的舆论引导与危机应对
人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。
内容概要:本文全面探讨了大学生沉迷网络游戏的现状及成因,强调该问题已严重影响大学生的学业和个人发展。据统计显示,中国大学生网络游戏成瘾患病率超过15%,问题广泛且严重。分析指出沉迷原因涵盖个人因素(如自我管理能力缺失、逃避现实压力)、家庭因素(例如家庭教育缺失和家庭氛围不和谐)、学校因素(如大学管理松散和校园文化活动匮乏),以及社会因素(例如网游设计吸引人和监管部门不严)。基于以上成因,提出了多层次综合治理方案,包括但不限于强化家庭教育和沟通、改善大学管理模式、丰富校园文化、加强网络游戏审查力度和社会心理健康辅导等方面的对策。 适用人群:本研究适用于高校辅导员、心理学家、教育政策决策人员,以及关心青年成长的社会各界人士。 使用场景及目标:本文旨在引起社会对该问题的关注,并为教育界和其他相关群体提供了详细的参考资料用于制定相应的干预措施,以减少大学生游戏成瘾情况的发生。此外,也可供家长学习科学育子知识。 其他说明:除了直接提出具体治理办法外,还特别提到了营造健康的网络文化环境的重要性,提倡多方协作共促学生健康发展。同时呼吁进一步加强对网络游戏产业的研究与管理,确保产业的良性发展的同时也能
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
矢量边界,行政区域边界,精确到乡镇街道,可直接导入arcgis使用
TI维也纳整流器设计.rar
自驾游中的手机APP推荐
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
视讯镜头专利复现,基本复现
,,OMRON CP1H PLC脉冲控制三轴伺服, 码垛机,实际项目,程序结构清析,有完整的注释,重复功能做成FB功能块,在其它项目可以导出直接用,MCGS触摸屏程序,有电气CAD图纸。 ,关键词:OMRON CP1H PLC;脉冲控制;三轴伺服;码垛机;程序结构清晰;完整注释;FB功能块;MCGS触摸屏程序;电气CAD图纸。,OMRON PLC三轴伺服脉冲控制程序:结构清晰、注释完整,FB功能块可复用,配合MCGS触摸屏及CAD图纸的实际项目应用
是一款基于JAVA的串口调试工具,支持波特率9600-115200,仅供参考学习使用,
,,CO2激光切割机雕刻机打标机写字机喷涂机巡边机控制软件,包含上位机和控制板,也可源码 视频展示只体现工作流程和加工效果,如果激光功率足够大最快速度能跑到每秒两米 支持文件格式说明: 控制版和上位机通信接口为百兆以太网接口,数据载体为标准TCP协议 1.g代码 2.打印图片 3.plt格式文件 4.激光机在切割有效线条时匀速切割 5.有效线条切割速度和空程速度分别设置 6.空程运行具备加减速控制 7.图片打印时上位机界面实时显示打印进度 8.打开的图片和图形文件可鼠标缩放和拖动 9.图片格式转并保存转完成的指定格式图片 10.手动回原点控制 ,核心关键词: CO2激光切割机; 雕刻机; 打标机; 写字机; 喷涂机; 巡边机; 控制软件; 上位机; 控制板; 源码; 视频展示; 工作流程; 加工效果; 激光功率; 速度; 两秒; 文件格式; g代码; 打印图片; plt格式文件; 有效线条切割; 空程速度设置; 加减速控制; 上位机界面实时显示; 图片缩放和拖动; 图片格式转换; 手动回原点控制。 关键词用分号隔开: CO2激光切割机; 喷涂机; 控制软件; g代码; 图片格式转