cocos2dx spine之一 :spine缓存 (c++ & lua)

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

cocos2dx spine之一 :spine缓存 (c++ & lua)的相关文章

【Spine】Spine Runtime for Delphi移植笔记(六) - spine.core.skeleton.binary

//////////////////////////////////////////////////////////////////////////////// //Generic delphi runtime v3.6 for Spine animation tool // //Runtime port by cjk ([email protected]) // //////////////////////////////////////////////////////////////////

【Spine】Spine Runtime for Delphi移植笔记(七) - spine.core.skeleton

//////////////////////////////////////////////////////////////////////////////// //Generic delphi runtime v3.6 for Spine animation tool // //Runtime port by cjk ([email protected]) // //////////////////////////////////////////////////////////////////

cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++

cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值得吐槽的是.这套流程在开发中差点儿是不可避免的,而cocos2d-x居然不把它作为一个公用接口暴露给开发人员,而须要我自己动手,真是无奈. 以下以一个简单的消息分发类为样例,演示怎样完毕这一工作. MessageDispatcher.h class MessageDispather { public

【Spine】Spine Runtime for Delphi移植笔记(二) - spine.math

//////////////////////////////////////////////////////////////////////////////// //Generic delphi runtime v3.6 for Spine animation tool // //Runtime port by cjk ([email protected]) // //////////////////////////////////////////////////////////////////

【Spine】Spine Runtime for Delphi移植笔记(三) - spine.types

//////////////////////////////////////////////////////////////////////////////// //Generic delphi runtime v3.6 for Spine animation tool // //Runtime port by cjk ([email protected]) // //////////////////////////////////////////////////////////////////

cocos2d-x学习笔记(c++与lua交互回调函数的处理)

本文假设读者已经会使用tolua++进行C++与lua之间的通讯 1.在头文件中定义注册回调函数,定义在MyClass类中 void register(unsigned short cmdID, LUA_FUNCTION func);//LUA_FUNCTION其实就是一个int void unregister(); 2.实现 void MyClass::register(unsigned short cmdID, LUA_FUNCTION func) { m_luaFunction = fun

cocos2dx 3.3 C++工程添加lua支持

准备工作: 1. 拷贝cocos2d-x-3.3rc0\external\lua整个文件夹到项目中(如myProject\cocos2d\external\lua) 2. 拷贝cocos2d-x-3.3rc0\cocos\scripting整个文件夹到项目中(如myProject\cocos2d\cocos\scripting) VS工程配置: 1. 解决方案中添加刚拷贝过来的libluacocos2d项目(添加现有项目: myProject\cocos2d\cocos\scripting\lu

cocos2d-x C++ 获取网络图片缓存并展示

#ifndef __HttpGetImg__ #define __HttpGetImg__ #include "cocos2d.h" #include "HttpRequest.h" #include "HttpClient.h" USING_NS_CC_EXT; using namespace std; USING_NS_CC; class HttpGetImg : public cocos2d::CCLayer { public: HttpG

spine在cocos2d-x中进行局部换肤

最近发现越来越多的游戏热衷用spine来做动画,做出来的效果真是生动美妙啊.我也来研究一下.期间就遇到了两个问题,一个是局部换肤的问题,一个是碰撞的时候.我先来解决局部换肤的问题. 看了看cocos2d-x 提供的spine的demo,虽然没有局部换肤但是有整体换肤的功能,我觉得这就是解决问题的突破口.在cocos2d-x3.4中,换肤的函数是SkeletonRenderer 类中的这个函数: bool setSkin (const std::string& skinName); 首先看看函数的