• 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)

  • 相关阅读:
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    win32创建控件的一些问题
    win32 sdk绘制ListBox控件
    VC++ WIN32 sdk实现按钮自绘详解 之二.
    win32 sdk 列表视图控件绘制
    win32 sdk树形控件的项拖拽实现
    MFC 用gdi绘制填充多边形区域
    vc 按钮自绘
  • 原文地址:https://www.cnblogs.com/HemJohn/p/4815998.html
Copyright © 2020-2023  润新知