cocos2x (c++/lua) spine 文件的预加载
在之前,筆者寫過一編博客,通過lua在加載場景加載spineAnimation動畫精靈,保存在table中,然后在游戲中創建動畫精靈時,提取加載好的spineAnimaiton中的
spSkeletonData來創建spineAnimation,但后來筆者發現重復創建spineAnimation時,全部相同spSkeletonData會重用同一個spSkeletonData,以下是spSkeletonData拷貝方法的源代碼:
spSkeleton* spSkeleton_create (spSkeletonData* data) {
int i, ii;
?
_spSkeleton* internal = NEW(_spSkeleton);
spSkeleton* self = SUPER(internal);
CONST_CAST(spSkeletonData*, self->data) = data;
?
self->bonesCount = self->data->bonesCount;
self->bones = MALLOC(spBone*, self->bonesCount);
?
for (i = 0; i < self->bonesCount; ++i) {
spBoneData* boneData = self->data->bones[i];
spBone* parent = 0;
if (boneData->parent) {
/* Find parent bone. */
for (ii = 0; ii < self->bonesCount; ++ii) {
if (data->bones[ii] == boneData->parent) {
parent = self->bones[ii];
break;
}
}
}
self->bones[i] = spBone_create(boneData, self, parent);
}
CONST_CAST(spBone*, self->root) = self->bones[0];
?
self->slotsCount = data->slotsCount;
self->slots = MALLOC(spSlot*, self->slotsCount);
for (i = 0; i < self->slotsCount; ++i) {
spSlotData *slotData = data->slots[i];
?
/* Find bone for the slotData's boneData. */
spBone* bone = 0;
for (ii = 0; ii < self->bonesCount; ++ii) {
if (data->bones[ii] == slotData->boneData) {
bone = self->bones[ii];
break;
}
}
self->slots[i] = spSlot_create(slotData, bone);
}
?
self->drawOrder = MALLOC(spSlot*, self->slotsCount);
memcpy(self->drawOrder, self->slots, sizeof(spSlot*) * self->slotsCount);
?
self->r = 1;
self->g = 1;
self->b = 1;
self->a = 1;
?
self->ikConstraintsCount = data->ikConstraintsCount;
self->ikConstraints = MALLOC(spIkConstraint*, self->ikConstraintsCount);
for (i = 0; i < self->data->ikConstraintsCount; ++i)
self->ikConstraints[i] = spIkConstraint_create(self->data->ikConstraints[i], self);
?
spSkeleton_updateCache(self);
?
return self;
}
?
在拷貝當中,骨骼數據確實新開辟一個內存,拷貝了一份新的spSkeletonData,但是,由于spSkeletonData屬于在table中保存的SkeletonAnimation中,受到SkeletonAnimation的影響,所以不能使用SkeletonAnimation中的spSkeletonData去創建另外一個SkeletonAnimation。
?
筆者也試過從lua中創建spSkeletonData數據,保存在table中,然后在游戲中傳遞spSkeletonData去創建SkeletonAnimation,
但在切換場景過程中,spSkeletonData會被釋放掉,所以不能被復用。
?
后來筆者從c++入手,將spSkeletonData保存在c++靜態的字典中,通過鍵值提取spSkeletonData去創建SkeletonAnimation,避免釋放問題。
以下是實現方法:
//SpineAnimation_new.h
#include <stdio.h>
#include "cocos/editor-support/spine/SkeletonAnimation.h"
#include "cocos/editor-support/spine/spine.h"
#include "spine/SkeletonRenderer.h"
#include "cocos2d.h"
?
using namespace spine;
using namespace std;
?
class SpineAnimation_new:spine::SkeletonAnimation
{
public:
? ? static SpineAnimation_new *createWithSkeletonData(spSkeletonData* skeletonData);
? ? static SpineAnimation_new *createWithKey(const std::string& key);
?? ?
? ? virtual ~SpineAnimation_new();
? ? spAnimationState* getState() {return SkeletonAnimation::getState();}
?? ?
?? ?
? ? spSkeletonData* getSkeletonData()
? ? {
? ? ? ? spSkeletonData*skData =SkeletonRenderer::getSkeleton()->data;
? ? ? ? return skData;
? ? }
?? ?
? ? static spSkeletonData*loadSkeletonData(const std::string& atlasFile,const std::string& jsonFile,const std::string& key);
? ? static map<const std::string,spSkeletonData*> skeletonDataMap;
? ? static void clear();
private:
? ? SpineAnimation_new(spSkeletonData*skeletonData);
? ? SpineAnimation_new(const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
};
?
#endif?
?
//SpineAnimation_new.cpp
?
?
#include "SpineAnimation_new.h"
#include "cocos2d.h"
#include "cocos/scripting/lua-bindings/manual/cocos2d/LuaScriptHandlerMgr.h"
#include "CCLuaStack.h"
#include "CCLuaEngine.h"
?
USING_NS_CC;
?
map<const std::string,spSkeletonData*> SpineAnimation_new::skeletonDataMap;
SpineAnimation_new *SpineAnimation_new::createWithSkeletonData(spSkeletonData* skeletonData)
{
? ? SpineAnimation_new* node = new (std::nothrow)SpineAnimation_new(skeletonData);
? ? node->autorelease();
? ? return node;
}
?
?
spSkeletonData*SpineAnimation_new::loadSkeletonData(const std::string& atlasFile,const std::string& jsonFile,const std::string& key)
{
? ? spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
? ? spSkeletonJson* json = spSkeletonJson_create(atlas);
? ? json->scale = 1;
? ? spSkeletonData* sd = spSkeletonJson_readSkeletonDataFile(json, jsonFile.c_str());
? ? SpineAnimation_new::skeletonDataMap.insert(pair<const std::string,spSkeletonData*>(key,sd));
? ? return sd;
}
?
SpineAnimation_new *SpineAnimation_new::createWithKey(const std::string& key)
{
? ? map<const std::string,spSkeletonData*>::iterator iter = SpineAnimation_new::skeletonDataMap.find(key);
? ? spSkeletonData* sd = iter->second;
? ? SpineAnimation_new*sa = createWithSkeletonData(sd);
? ? return sa;
}
?
?
SpineAnimation_new::~SpineAnimation_new()
{
? ? ScriptHandlerMgr::getInstance()->removeObjectAllHandlers((void*)this);
}
?
SpineAnimation_new::SpineAnimation_new(spSkeletonData*skeletonData):
SkeletonAnimation(skeletonData)
{
?? ?
}
SpineAnimation_new::SpineAnimation_new(const std::string& skeletonDataFile, const std::string& atlasFile, float scale):SkeletonAnimation(skeletonDataFile,atlasFile,scale)
{
}
?
void SpineAnimation_new::clear()
{
? ? SpineAnimation_new::skeletonDataMap.clear();
}
?
(轉載時請注明出處,from 博客園:HemJohn)
轉載于:https://www.cnblogs.com/HemJohn/p/4815998.html
總結
以上是生活随笔為你收集整理的cocos2x (c++/lua) spine 文件的预加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 整数数组的定义,然后输入一个整数X,假定
- 下一篇: 如何制作美味且健康的晚餐?