問題:最近項目中須要作一個loading個界面,界面中間有一個角色人物走動的動畫,在顯示這個loading界面的時候加載資源,項目是用cocos2d-x lua實現的,界面作出來後發如今加載資源的時候界面會卡住。api
緣由: 由於使用的不是異步加載,並且cocos2d-x沒有綁定異步加載資源的api到lua中,其實在lua中實現不了異步。數組
想經過在lua中啓動一個線程去加載資源,但lua是不支持多線程的,只有協程,但並非真正意義上的多線程,只不過是函數間執行權的相互交換。多線程
解決思路:異步
1.編寫綁定到Lua中異步資源加載接口類函數
AsynResLoader.h
工具
#ifndef _ASYNRESLOADER_H_ #define _ASYNRESLOADER_H_ #include "cocos2d.h" USING_NS_CC; //供Lua調用的異步的資源加載器 class AsynResLoader: public CCObject { private: int count; int total; //lua回調方法 int mLuaCallback; public: //建立一個異步資源加載器 static AsynResLoader* create(); //異步加載紋理 void asynLoadTexture(CCArray* paths, int luaCallbck); //加載回調 void callback(CCObject* pSender); }; #endif
AsynResLoader.cpp動畫
#include "AsynResLoader.h" #include "CCLuaEngine.h" //建立一個異步資源加載器 AsynResLoader* AsynResLoader::create(){ AsynResLoader* instance = new AsynResLoader; if (instance) { instance->autorelease(); return instance; } return NULL; } //異步加載紋理 void AsynResLoader::asynLoadTexture(CCArray* paths, int luaCallback){ this->count = 0; this->total = paths->count(); this->mLuaCallback = luaCallback; for(int idx = 0; idx <total; idx++) { const char* path = ((CCString*)paths->objectAtIndex(idx))->getCString(); CCLOG("asynLoadTexture PATH idx=%d : %s",idx,path); CCTextureCache::sharedTextureCache()->addImageAsync(path, this, callfuncO_selector(AsynResLoader::callback)); } } //紋理加載回調方法 void AsynResLoader::callback(CCObject*){ this->count++; //當資源加載完成時,回調指定的lua函數 if (this->count >= this->total) { CCLOG("asyn load res completed.."); if (this->mLuaCallback) { CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack(); //第一個參數是函數的整數句柄,第二個參數是函數參數個數 pStack->executeFunctionByHandler(this->mLuaCallback,0); pStack->clean(); CCLOG("call lua function.."); } } }
2.使用tolua++工具把類綁定到lua中(點擊查看使用方法)this
3.在lua中建立資源路徑數組,調用接口方法,把路徑數組和回調函數傳遞進去lua
lua代碼:spa
function asynLoadTexture(callback) local pngs = CCArray:create() -- Buff動畫幀路徑 for _, anim in ipairs(buff_anim_config.buff_anim_config) do pngs:addObject(CCString:create(anim.png)) end -- 技能動畫幀路徑 for k, anim in ipairs(skill_anim_config.skill_anim_config) do pngs:addObject(CCString:create(anim.png)) end AsynResLoader:create():asynLoadTexture(pngs,callback) end
實質就是lua調用C++方法實現異步加載資源。