溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

cocos2d-x lua分支加載ccbi文件

發(fā)布時(shí)間:2020-06-29 14:49:31 來(lái)源:網(wǎng)絡(luò) 閱讀:1948 作者:孫少磊 欄目:游戲開(kāi)發(fā)

cocos2d-x lua的分支竟然沒(méi)有提供擴(kuò)展包里面的類,苦大了我們啊,經(jīng)過(guò)各種嘗試摸索,終于OKcocos2d-x lua分支加載ccbi文件

不完美處就是留下一些使用的潛規(guī)則:
1、所有的控件名字不得重復(fù)(要根據(jù)控件名字注冊(cè)lua的回調(diào)方法)
2、如果是成員變量名字格式為 空間名-空間類型 比如:second_text-CCLabelTTF
3、點(diǎn)擊事件的lua回調(diào)方法名為 控件名_onClicked 比如:button_onClicked
4、所有的成員變量需要暴露給lua,通過(guò)lua的函數(shù)調(diào)用以傳參的方式暴露 格式為 set_控件名例子:set_second_text

 
剩下就是代碼實(shí)現(xiàn)的機(jī)制了,先上代碼,下面部分是要暴露給lua的,具體怎么暴露參看tolua++
  1. CCNode* CCBIFactory::loadCCBI(CCScene *pScene, char* ccbiPath, char* loaderName){  
  2.  
  3.     CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();  
  4.  
  5.     CCNodeLoader*nodeLoader = GameUILoader::loader();  
  6.  
  7.     ccNodeLoaderLibrary->registerCCNodeLoader(loaderName, nodeLoader);  
  8.  
  9.     CCBReader * ccbReader = new CCBReader(ccNodeLoaderLibrary);  
  10.  
  11.     CCNode * node = ccbReader->readNodeGraphFromFile(ccbiPath, this);  
  12.  
  13.     ccbReader->autorelease();  
  14.  
  15.     return node;  
  16.  
  17. }  
  18.  

在下面就是CCBI所映射的類了,在C++中一個(gè)ccbi是對(duì)應(yīng)著一個(gè)類存在的,里面包含了所有控件回調(diào)的注冊(cè),實(shí)例是在解析ccbi文件的時(shí)候創(chuàng)建的,如果要用C++ lua 的情況下肯定不能為每個(gè)ccbi都創(chuàng)建一個(gè)類,所以就需要一個(gè)通用格式的類定義,需要解決的問(wèn)題有一下幾點(diǎn)

1、要把所有可點(diǎn)擊控件的點(diǎn)擊事件轉(zhuǎn)到lua的函數(shù)中,在回調(diào)里目前無(wú)法獲取到被點(diǎn)擊對(duì)象的標(biāo)識(shí),換句話說(shuō),根本不知道哪個(gè)控件點(diǎn)擊的,C++中是根據(jù)不同的回調(diào)函數(shù)來(lái)區(qū)分的,但是要在頭文件中把相應(yīng)方法定義好,既然要通用,肯定不能確定該有多少個(gè)控件,這步就卡這了。我們的解決方案是把所有的控件全部在onAssignCCBMemberVariable執(zhí)行的時(shí)候記錄下來(lái)m_uid 和控件名,把這兩個(gè)值存到map結(jié)構(gòu)里面,根據(jù)m_uid來(lái)區(qū)分誰(shuí)觸發(fā)的點(diǎn)擊事件,點(diǎn)擊事件觸發(fā)后由C++根據(jù)map結(jié)構(gòu)中的值查詢出控件名字,然后調(diào)用lua中按照此控件名字命名的函數(shù),剩下的就交給lua了。

2、成員變量綁定的控件要導(dǎo)出到lua中,這點(diǎn)也挺惡心,因?yàn)椴恢烙卸嗌賯€(gè),不能直接在頭文件定義,而且還獲取不到控件類型。解決方法喝上一步差不多,我們是在所有這種控件的名字后面加上 -類型 比如:second_text-CCLabelTTF ,然后程序也是在onAssignCCBMemberVariable方法執(zhí)行的時(shí)候調(diào)用lua里面和空間名字相同的函數(shù)把對(duì)象給暴露出去比如控件名是second_text-CCLabelTTF,那個(gè)回調(diào)函數(shù)為set_second_test(obj),  obj為CCLabelTTF的對(duì)象


 

廢話不多說(shuō)了,上代碼:

  1. #include "GameUILayer.h"  
  2.  
  3. #include "CCLuaEngine.h"  
  4.  
  5. USING_NS_CC;  
  6.  
  7. USING_NS_CC_EXT;  
  8.  
  9. using namespace std;  
  10.  
  11. void GameUILayer::onNodeLoaded(cocos2d::CCNode * pNode,  cocos2d::extension::CCNodeLoader * pNodeLoader) {  
  12.  
  13. }  
  14.  
  15. SEL_MenuHandler GameUILayer::onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) {  
  16.  
  17.     return NULL;  
  18.  
  19. }  
  20.  
  21. SEL_CCControlHandler GameUILayer::onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName) {  
  22.  
  23.     string name = pSelectorName->getCString();     // 控件名字  
  24.  
  25.     CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this, name.c_str(), GameUILayer::onClicked);  
  26.     return NULL;  
  27. }  
  28.  
  29. bool GameUILayer::onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode) {  
  30.     CCNode *button = NULL;  
  31.     string name = pMemberVariableName->getCString();  
  32.     XIAOLEI_CCB_MEMBERVARIABLEASSIGNER_GLUE(this, name.c_str(), CCNode *, button);  
  33.     int index = name.find_first_of('-', 0);  
  34.     if (index != string::npos)  
  35.     {  
  36.         char* funcName = (char*) (("set_" + name.substr(0,index)).c_str());  
  37.         char* typeName = (char*) name.substr(index+1).c_str();  
  38.         CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();  
  39.         pEngine->registerCCBIMember(funcName, button, typeName);     // 這個(gè)函數(shù)是我們改動(dòng)cocos2d源碼增加的,很簡(jiǎn)單就是調(diào)用lua的函數(shù)并且傳過(guò)去一個(gè)CCObject的對(duì)象作為參數(shù)  
  40.     }  
  41.     objectNameMapping.insert(map<int, string>::value_type(button->m_uID, name));     // 注冊(cè)m_uid和控件名的綁定  
  42.     return false;  
  43. }  
  44.  
  45. void GameUILayer::onClicked(CCObject * pSender, cocos2d::extension::CCControlEventpCCControlEvent) {  
  46. // 所有控件統(tǒng)一注冊(cè)這一個(gè)回調(diào)函數(shù)  
  47.     map<int, string>::iterator iter = objectNameMapping.find(pSender->m_uID);  
  48.     if(iter != objectNameMapping.end())  
  49.     {  
  50.         CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();  
  51.         pEngine->executeGlobalFunction((iter->second+"_onClicked").c_str());     // 根據(jù)控件名調(diào)用相應(yīng)的lua方法  
  52.     }  
  53. }  
  54.  

頭文件什么的就不提供了,想要正常運(yùn)行還要實(shí)現(xiàn)以下CCLuaEngine:: registerCCBIMember 這個(gè)方法,這點(diǎn)就不用說(shuō)了吧,目前在外面,等回去后把lua代碼也貼出來(lái)

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI