cocos2d-x lua的分支竟然没有提供扩展包里面的类,苦大了我们啊,经过各种尝试摸索,终于OK
不完美处就是留下一些使用的潜规则:
1、所有的控件名字不得重复(要根据控件名字注册lua的回调方法)
2、如果是成员变量名字格式为 空间名-空间类型 比如:second_text-CCLabelTTF
3、点击事件的lua回调方法名为 控件名_onClicked 比如:button_onClicked
4、所有的成员变量需要暴露给lua,通过lua的函数调用以传参的方式暴露 格式为 set_控件名例子:set_second_text
剩下就是代码实现的机制了,先上代码,下面部分是要暴露给lua的,具体怎么暴露参看tolua++
CCNode* CCBIFactory::loadCCBI(CCScene *pScene,char* ccbiPath,char* loaderName){
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();
CCNodeLoader*nodeLoader = GameUILoader::loader();
ccNodeLoaderLibrary->registerCCNodeLoader(loaderName, nodeLoader);
CCBReader * ccbReader =newCCBReader(ccNodeLoaderLibrary);
CCNode * node = ccbReader->readNodeGraphFromFile(ccbiPath,this);
ccbReader->autorelease();
returnnode;
}
在下面就是CCBI所映射的类了,在C++中一个ccbi是对应着一个类存在的,里面包含了所有控件回调的注册,实例是在解析ccbi文件的时候创建的,如果要用C++ lua 的情况下肯定不能为每个ccbi都创建一个类,所以就需要一个通用格式的类定义,需要解决的问题有一下几点
1、要把所有可点击控件的点击事件转到lua的函数中,在回调里目前无法获取到被点击对象的标识,换句话说,根本不知道哪个控件点击的,C++中是根据不同的回调函数来区分的,但是要在头文件中把相应方法定义好,既然要通用,肯定不能确定该有多少个控件,这步就卡这了。我们的解决方案是把所有的控件全部在onAssignCCBMemberVariable执行的时候记录下来m_uid 和控件名,把这两个值存到map结构里面,根据m_uid来区分谁触发的点击事件,点击事件触发后由C++根据map结构中的值查询出控件名字,然后调用lua中按照此控件名字命名的函数,剩下的就交给lua了。
2、成员变量绑定的控件要导出到lua中,这点也挺恶心,因为不知道有多少个,不能直接在头文件定义,而且还获取不到控件类型。解决方法喝上一步差不多,我们是在所有这种控件的名字后面加上 -类型 比如:second_text-CCLabelTTF ,然后程序也是在onAssignCCBMemberVariable方法执行的时候调用lua里面和空间名字相同的函数把对象给暴露出去比如控件名是second_text-CCLabelTTF,那个回调函数为set_second_test(obj), obj为CCLabelTTF的对象
废话不多说了,上代码:
#include "GameUILayer.h"
#include "CCLuaEngine.h"
USING_NS_CC;
USING_NS_CC_EXT;
usingnamespacestd;
voidGameUILayer::onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader) {
}
SEL_MenuHandler GameUILayer::onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) {
returnNULL;
}
SEL_CCControlHandler GameUILayer::onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName) {
string name = pSelectorName->getCString();// 控件名字
CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this, name.c_str(), GameUILayer::onClicked);
returnNULL;
}
boolGameUILayer::onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode) {
CCNode *button = NULL;
string name = pMemberVariableName->getCString();
XIAOLEI_CCB_MEMBERVARIABLEASSIGNER_GLUE(this, name.c_str(), CCNode *, button);
intindex = name.find_first_of('-', 0);
if(index != string::npos)
{
char* funcName = (char*) (("set_"+ name.substr(0,index)).c_str());
char* typeName = (char*) name.substr(index+1).c_str();
CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
pEngine->registerCCBIMember(funcName, button, typeName);// 这个函数是我们改动cocos2d源码增加的,很简单就是调用lua的函数并且传过去一个CCObject的对象作为参数
}
objectNameMapping.insert(map::value_type(button->m_uID, name));// 注册m_uid和控件名的绑定
returnfalse;
}
voidGameUILayer::onClicked(CCObject * pSender, cocos2d::extension::CCControlEventpCCControlEvent) {
// 所有控件统一注册这一个回调函数
map::iterator iter = objectNameMapping.find(pSender->m_uID);
if(iter != objectNameMapping.end())
{
CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
pEngine->executeGlobalFunction((iter->second+"_onClicked").c_str());// 根据控件名调用相应的lua方法
}
}
头文件什么的就不提供了,想要正常运行还要实现以下CCLuaEngine::registerCCBIMember 这个方法,这点就不用说了吧,目前在外面,等回去后把lua代码也贴出来
本文介绍在Cocos2d-xLua环境中如何处理控件注册及成员变量暴露的问题,通过自定义方法实现了点击事件传递到Lua脚本,并解决了控件名与类型的绑定。
2981

被折叠的 条评论
为什么被折叠?



