cocos2dx版本为3.10
1.在使用spine的过程中,发现了一个比较严重的问题:每次创建SkeletonAnimation的时候都会很卡,即使是使用同一个骨骼数据skeletonData。
跟踪代码发现,在每次调用函数spine::SkeletonAnimation::createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);的时候都需要重新解析一次skeletonDataFile产生骨骼数据skeletonData。
2.问题找到了,那要想个最简单的解决办法,就是将骨骼数据skeletonData缓存起来,需要的时候再取出来使用。
3.直接修改SkeletonAnimation的源码
①在头文件SkeletonAnimation.h中增加对应函数以及成员变量
1 public: 2 //从缓存中创建Animation 3 static SkeletonAnimation* createFromCache(const std::string& skeletonDataKeyName); 4 5 //将文件读入到cache中(skeletonDataKeyName参数为自定义的骨骼数据名称) 6 static spSkeletonData* readSkeletonDataToCache(const std::string& skeletonDataKeyName, const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1); 7 8 //从cache中得到skeletonData(skeletonDataKeyName参数为自定义的骨骼数据名称) 9 static spSkeletonData* getSkeletonDataFromCache(const std::string& skeletonDataKeyName); 10 11 //从cache中删除skeletonData(skeletonDataKeyName参数为自定义的骨骼数据名称) 12 static bool removeSkeletonData(const std::string& skeletonDataKeyName); 13 14 //清理所有skeletonData 15 static void removeAllSkeletonData(); 16 17 //是否在cache中存在对应的骨骼数据skeletonData 18 static bool isExistSkeletonDataInCache(const std::string& skeletonDataKeyName); 19 private: 20 struct SkeletonDataInCache{ 21 spSkeletonData* _skeleton_data; //记录骨骼数据 22 spAtlas* _atlas; //记录对应图片块信息 23 }; 24 typedef std::map<std::string, SkeletonDataInCache>::iterator ItSkeletonData; 25 static std::map<std::string, SkeletonDataInCache> _all_skeleton_data_cache; //记录所有的skeletonData缓冲区
②在源文件SkeletonAnimation.cpp中增加对应函数实现以及初始化静态成员变量
1 SkeletonAnimation* SkeletonAnimation::createFromCache(const std::string& skeletonDataKeyName) 2 { 3 if (spSkeletonData* skeleton_data = getSkeletonDataFromCache(skeletonDataKeyName)){ 4 SkeletonAnimation* node = new SkeletonAnimation(skeleton_data, false); 5 node->autorelease(); 6 return node; 7 } 8 9 return nullptr; 10 } 11 12 spSkeletonData* SkeletonAnimation::readSkeletonDataToCache(const std::string& skeletonDataKeyName, const std::string& skeletonDataFile, const std::string& atlasFile, float scale /*= 1*/) 13 { 14 ItSkeletonData it = _all_skeleton_data_cache.find(skeletonDataKeyName); 15 16 if (it == _all_skeleton_data_cache.end()){ 17 SkeletonDataInCache skeleton_data_in_cache; 18 skeleton_data_in_cache._atlas = nullptr; 19 skeleton_data_in_cache._skeleton_data = nullptr; 20 21 skeleton_data_in_cache._atlas = spAtlas_createFromFile(atlasFile.c_str(), 0); 22 CCASSERT(skeleton_data_in_cache._atlas, "readSkeletonDataToCachereading Error atlas file."); 23 24 spSkeletonJson* json = spSkeletonJson_create(skeleton_data_in_cache._atlas); 25 json->scale = scale; 26 skeleton_data_in_cache._skeleton_data = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str()); 27 CCASSERT(skeleton_data_in_cache._skeleton_data, json->error ? json->error : "readSkeletonDataToCache Error reading skeleton data file."); 28 spSkeletonJson_dispose(json); 29 30 if (skeleton_data_in_cache._atlas && skeleton_data_in_cache._skeleton_data){ 31 _all_skeleton_data_cache[skeletonDataKeyName] = skeleton_data_in_cache; 32 33 return skeleton_data_in_cache._skeleton_data; 34 } 35 else{ //错误处理,释放创建的资源 36 if (skeleton_data_in_cache._skeleton_data){ 37 spSkeletonData_dispose(skeleton_data_in_cache._skeleton_data); 38 } 39 40 if (skeleton_data_in_cache._atlas){ 41 spAtlas_dispose(skeleton_data_in_cache._atlas); 42 } 43 } 44 } 45 46 return nullptr; 47 } 48 49 spSkeletonData* SkeletonAnimation::getSkeletonDataFromCache(const std::string& skeletonDataKeyName) 50 { 51 ItSkeletonData it = _all_skeleton_data_cache.find(skeletonDataKeyName); 52 if (it != _all_skeleton_data_cache.end()){ 53 return it->second._skeleton_data; 54 } 55 56 return nullptr; 57 } 58 59 bool SkeletonAnimation::removeSkeletonData(const std::string& skeletonDataKeyName) 60 { 61 ItSkeletonData it = _all_skeleton_data_cache.find(skeletonDataKeyName); 62 if (it != _all_skeleton_data_cache.end()){ 63 if (it->second._skeleton_data) spSkeletonData_dispose(it->second._skeleton_data); 64 if (it->second._atlas) spAtlas_dispose(it->second._atlas); 65 66 _all_skeleton_data_cache.erase(it); 67 return true; 68 } 69 70 return false; 71 } 72 73 void SkeletonAnimation::removeAllSkeletonData() 74 { 75 for (ItSkeletonData it = _all_skeleton_data_cache.begin(); it != _all_skeleton_data_cache.end(); ++it){ 76 if (it->second._skeleton_data) spSkeletonData_dispose(it->second._skeleton_data); 77 if (it->second._atlas) spAtlas_dispose(it->second._atlas); 78 } 79 80 _all_skeleton_data_cache.clear(); 81 } 82 83 bool SkeletonAnimation::isExistSkeletonDataInCache(const std::string& skeletonDataKeyName) 84 { 85 ItSkeletonData it = _all_skeleton_data_cache.find(skeletonDataKeyName); 86 if (it != _all_skeleton_data_cache.end()){ 87 return true; 88 } 89 90 return false; 91 } 92 93 std::map<std::string, SkeletonAnimation::SkeletonDataInCache> SkeletonAnimation::_all_skeleton_data_cache; //初始化静态成员
4.好了,重新编译libcocos2d后,下面为c++的使用方式。
①在需要使用的地方调用对应的接口进行创建
1 //判断是否存在自定义名称为GirlSkeletonDataKey的骨骼数据 2 spSkeletonData* skeleton_data = spine::SkeletonAnimation::getSkeletonDataFromCache("GirlSkeletonDataKey"); 3 4 //如果不存在对应的骨骼数据,则读入解析一遍 5 if (!skeleton_data){ 6 skeleton_data = spine::SkeletonAnimation::readSkeletonDataToCache("GirlSkeletonDataKey", "girl.json", "girl.atlas"); 7 } 8 9 if (skeleton_data){ 10 //直接使用骨骼数据创建动画 11 spine::SkeletonAnimation* skeleton_animation = SkeletonAnimation::createWithData(skeleton_data); 12 13 //也可以使用这个接口,效果和createWithData一样 14 //spine::SkeletonAnimation* skeleton_animation = SkeletonAnimation::createFromCache("GirlSkeletonDataKey"); 15 }
②在需要释放数据的地方调用这个接口释放所有的骨骼数据缓存数据
1 spine::SkeletonAnimation::removeAllSkeletonData();
5.lua使用方式
①直接进入cocos2d-x-3.10\tools\tolua,运行genbindings.py来重新生成c++和lua之间的绑定文件
②重新编译libluacocos2d
③下面为lua的使用方式
1 --由于lua中没有绑定spSkeletonData,所以readSkeletonDataToCache的函数返回值无效(getSkeletonDataFromCache函数也一样),不能对返回值进行判断! 2 if not sp.SkeletonAnimation:isExistSkeletonDataInCache("GirlSkeletonDataKey") then 3 sp.SkeletonAnimation:readSkeletonDataToCache("GirlSkeletonDataKey", "girl.json", "girl.atlas"); 4 end 5 --由于cocos2dx_spine.ini中没对SkeletonAnimation::createWithData函数进行绑定,所以这个函数在lua中不能使用 6 local skeleton_animation = sp.SkeletonAnimation:createFromCache("GirlSkeletonDataKey");
以上,完。
时间: 2024-10-13 08:27:53