zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    浅析锂电池保护板(BMS)系统设计思路(一)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务(三)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务(二)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务(一)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(五)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(四)
    手把手,嘴对嘴,讲解UCOSII嵌入式操作系统的任务调度策略(三)
    精度要求较高的场景对float和double浮点数据的处理
    小数形式的十进制数字转换为二进制(附过程)
    mysql 隐式转换问题(案例二)
  • 原文地址:https://www.cnblogs.com/HemJohn/p/4815998.html
Copyright © 2011-2022 走看看