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