zoukankan      html  css  js  c++  java
  • spine实现预加载(一)

    前言

      本文实现了spine动画的预加载,解决在战斗等大量加载spine动画的时候出现卡顿现象。

    这里使用和修改三个类,直接修改的源码,当然你也可以继承LuaSkeletonAnimation,自己封装一个类。这里做个例子,

    不自己写类,直接改源码。如果想自己写,绑定到lua,看我别的帖子。废话不多说,入主题。

    在之前对图片 应该对图片进行异步加载,详细以后再说。

    版本:quicklua 3.3  win vs2012

    原理

    先分析下,LuaSkeletonAnimation类

    class LuaSkeletonAnimation: public spine::SkeletonAnimation {
    public:
        static LuaSkeletonAnimation* createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale = 1);
    
        LuaSkeletonAnimation (const char* skeletonDataFile, const char* atlasFile, float scale = 1);
    
        virtual ~LuaSkeletonAnimation();
    };

    LuaSkeletonAnimation 继承自 SkeletonAnimation类。

    在lua_cocos2dx_spine_manual.cpp中可以看到,在lua层调用 create 方法实际是 调用的LuaSkeletonAnimation的 createWithFile 方法

    所以我们把新的方法也放到这里,当然你也可以直接放到SkeletonAnimation类中。建议在此处。

    再看下SkeletonAnimation类:

        static SkeletonAnimation* createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
        static SkeletonAnimation* createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 1);
        static SkeletonAnimation* createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);

    创建spine动画有两种方法,分别是createwithfile和createwithdata。

    createWithFile是通过加载动作数据马上进行创建,如果spine动画中的json文件大小超过100k时,会出现卡顿现象,如果动画文件偏小,可以使用这个方法来创建动画。createWithData是通过预加载,保存动画数据在spSkeletonData中,然后通过实现创建动画。

    上面这些我相信你们一看就懂吧。 总体来讲:

    lua 层使用,createwithfile 方法创建,然后保存在table 中,实现预加载 。在使用的时候使用createWithData,创建动画。

    createWithData方法需要的参数是spSkeletonData,我们需要封装一个获取spSkeletonData的方法,具体看LuaSkeletonAnimation的爷爷类。

    c++代码的修改

    (1)SkeletonAnimation.h:

    spSkeletonData* getSkeletonData();

      SkeletonAnimation.cpp 实现

    spSkeletonData* SkeletonAnimation::getSkeletonData(){
    
       spSkeletonData*skData =SkeletonRenderer::getSkeleton()->data;
    
       return skData;
    }

    (2)LuaSkeletonAnimation.h

    class LuaSkeletonAnimation: public spine::SkeletonAnimation {
    public:
        static LuaSkeletonAnimation* createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale = 1);
    
        // preload spine   添加下面两个方法
        static LuaSkeletonAnimation* createWithSkeletonAnimation(SkeletonAnimation* skeletonAnimation);
        LuaSkeletonAnimation(SkeletonAnimation* spineData);
    
        LuaSkeletonAnimation (const char* skeletonDataFile, const char* atlasFile, float scale = 1);
    
        virtual ~LuaSkeletonAnimation();
    };

    说明:

    createWithSkeletonAnimation方法,为了减少导出自定义类,所以参数是 SkeletonAnimation。
    LuaSkeletonAnimation::LuaSkeletonAnimation (const char* skeletonDataFile, const char* atlasFile, float scale)
    : spine::SkeletonAnimation(skeletonDataFile, atlasFile, scale)
    {
        
    }
    
    LuaSkeletonAnimation::LuaSkeletonAnimation(SkeletonAnimation* spineData)
    : spine::SkeletonAnimation(spineData->getSkeletonData())
    {
    
    }
    LuaSkeletonAnimation::~LuaSkeletonAnimation()
    {
        ScriptHandlerMgr::getInstance()->removeObjectAllHandlers((void*)this);
    }
    
    LuaSkeletonAnimation* LuaSkeletonAnimation::createWithFile (const char* skeletonDataFile, const char* atlasFile, float scale)
    {
        LuaSkeletonAnimation* node = new (std::nothrow) LuaSkeletonAnimation(skeletonDataFile, atlasFile, scale);
        node->autorelease();
        return node;
    }
    
    LuaSkeletonAnimation* LuaSkeletonAnimation::createWithSkeletonAnimation(SkeletonAnimation* skeletonAnimation)
    {    
        LuaSkeletonAnimation* node = new (std::nothrow) LuaSkeletonAnimation(skeletonAnimation);
        node->autorelease();
        return node;
    }

    改好上面两个类。可以使用cocos2dx自带的脚本重新tolua一下。这里 直接改代码吧,省时有效。。。嘎嘎、、

    lua_cocos2dx_spine_manual.cpp

    1.

    static int lua_cocos2dx_CCSkeletonAnimation_createWithSkeletonAnimation(lua_State* L)
    {
        if (nullptr == L)
            return 0 ;
        
        int argc = 0;
        
    #if COCOS2D_DEBUG >= 1
        tolua_Error tolua_err;
        if (!tolua_isusertable(L,1,"sp.SkeletonAnimation",0,&tolua_err)) goto tolua_lerror;
    #endif
        
        argc = lua_gettop(L) - 1;
        
        if (1 == argc)
        {
            //TODO 
            SkeletonAnimation* skeletonAnimation = (SkeletonAnimation*)tolua_tousertype(L, 2, 0);
            auto tolua_ret = LuaSkeletonAnimation::createWithSkeletonAnimation(skeletonAnimation);
                  
            int nID = (tolua_ret) ? (int)tolua_ret->_ID : -1;
            int* pLuaID = (tolua_ret) ? &tolua_ret->_luaID : NULL;
            toluafix_pushusertype_ccobject(L, nID, pLuaID, (void*)tolua_ret,"sp.SkeletonAnimation");
            return 1;
        } 
    #if COCOS2D_DEBUG >= 1
    tolua_lerror:
        tolua_error(L,"#ferror in function 'createWithSkeletonAnimation'.",&tolua_err);
    #endif
        return 0;
    }

    2.static void extendCCSkeletonAnimation(lua_State* L)方法中添加一行:

     tolua_function(L, "createWithSkeletonAnimation", lua_cocos2dx_CCSkeletonAnimation_createWithSkeletonAnimation);

    lua使用及预加载

    上面代码改好之后,编译一下,跑起来程序,在lua测试一下,能不能正常调用函数。OK的话,就可以写代码  预加载了。

    在项目中我们一般要有个loadlayer 吧需要的音乐 图片 spine等预加载进去。这里测试一下就不写了、

    首先我们要封装一下 sp.SkeletonAnimation

    local SpineNode = class("SpineNode", function(spineName)
        spineName = "ceshi"
        --预加载列表有,就直接使用
        if LoadingManager:isSpineLoad(spineName) then
            dump("****************preload:"..spineName)
            do return sp.SkeletonAnimation:createWithSkeletonAnimation(LoadingManager.preloadSpines[spineName]) end 
        end
        
        if not cc.FileUtils:getInstance():isFileExist(spineName..".json") then
            print("Ani ERROR: not found " .. spineName .. "
    ")
            print(debug.traceback("", 2))
           spineName = "ceshi"
        end
    
        local s_pPathSpineBoyJson       = spineName..".json"
        local s_pPathSpineBoyAtlas       = spineName..".atlas"
    
        return sp.SkeletonAnimation:create(s_pPathSpineBoyJson, s_pPathSpineBoyAtlas, 1)
    end)

    其他需要 的方法自己封装几个。这里不写了。

    在整个统一的预加载资源类 ,提前加载spine 等,就可以了。

    注释:

    可以使用 createWithData ,添加一个 getAnimationData的方法。原理是一样的。

    以后会追加一篇关于lua异步加载 spine图片的文章。

    追加:

    先create 一个母本,在添加到缓存数组的时候,记得retain一下。最后记得释放release。

    要不然创建母本之后,会自己释放掉,导致直接崩溃。

    总结

      兄弟们那,一定要多看源码啊。。。流程应该很清晰了吧、。、、少年们应该能看懂了。交流加我QQ776274781 。大神勿喷。。

  • 相关阅读:
    MSSQL—列记录合并
    MSSQL—字符串分离(Split函数)
    如何在ASP.NET Core中自定义Azure Storage File Provider
    从零开始实现ASP.NET Core MVC的插件式开发(六)
    对ASP.NET程序员非常有用的85个工具
    vs-code 配置
    idea-plugin
    VirtualBox中CentOS遇到的问题
    监听器
    线程组复杂场景
  • 原文地址:https://www.cnblogs.com/zhangfeitao/p/5019355.html
Copyright © 2011-2022 走看看