cocos2d-x lua分支加载ccbi文件

本文介绍了一种解决cocos2d-xlua分支未提供扩展包类问题的方法,通过特定规则实现了控件与Lua脚本的交互,包括控件名称注册、成员变量暴露及点击事件回调。

在此向作者致敬,文章地址:http://softking.blog.51cto.com/6440674/1120550

cocos2d-x lua的分支竟然没有提供扩展包里面的类,苦大了我们啊,经过各种尝试摸索,终于OKcocos2d-x <wbr>lua分支加载ccbi文件

不完美处就是留下一些使用的潜规则:
1、所有的控件名字不得重复(要根据控件名字注册lua的回调方法)
2、如果是成员变量名字格式为 空间名-空间类型 比如:second_text-CCLabelTTF
3、点击事件的lua回调方法名为 控件名_onClicked 比如:button_onClicked
4、所有的成员变量需要暴露给lua,通过lua的函数调用以传参的方式暴露 格式为 set_控件名例子:set_second_text

 
剩下就是代码实现的机制了,先上代码,下面部分是要暴露给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++中一个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的对象


 

废话不多说了,上代码:

 
  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);     // 这个函数是我们改动cocos2d源码增加的,很简单就是调用lua的函数并且传过去一个CCObject的对象作为参数  
  40.     }  
  41.     objectNameMapping.insert(map<int, string>::value_type(button->m_uID, name));     // 注册m_uid和控件名的绑定  
  42.     return false;  
  43. }  
  44.  
  45. void GameUILayer::onClicked(CCObject * pSender, cocos2d::extension::CCControlEventpCCControlEvent) {  
  46. // 所有控件统一注册这一个回调函数  
  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());     // 根据控件名调用相应的lua方法  
  52.     }  
  53. }  
  54.  

先看效果: https://renmaiwang.cn/s/jkhfz Hue系列产品将具备高度的个性化定制能力,并且借助内置红、蓝、绿三原色LED的灯泡,能够混合生成1600万种不同色彩的灯光。 整个操作流程完全由安装于iPhone上的应用程序进行管理。 这一创新举措为智能照明控制领域带来了新的启示,国内相关领域的从业者也积极投身于相关研究。 鉴于Hue产品采用WiFi无线连接方式,而国内WiFi网络尚未全面覆盖,本研究选择应用更为普及的蓝牙技术,通过手机蓝牙与单片机进行数据交互,进而产生可调节占空比的PWM信号,以此来控制LED驱动电路,实现LED的调光功能以及DIY调色方案。 本文重点阐述了一种基于手机蓝牙通信的LED灯设计方案,该方案受到飞利浦Hue智能灯泡的启发,但考虑到国内WiFi网络的覆盖限制,故而选用更为通用的蓝牙技术。 以下为相关技术细节的详尽介绍:1. **智能照明控制系统**:智能照明控制系统允许用户借助手机应用程序实现远程控制照明设备,提供个性化的调光及色彩调整功能。 飞利浦Hue作为行业领先者,通过红、蓝、绿三原色LED的混合,能够呈现1600万种颜色,实现了全面的定制化体验。 2. **蓝牙通信技术**:蓝牙技术是一种低成本、短距离的无线传输方案,工作于2.4GHz ISM频段,具备即插即用和强抗干扰能力。 蓝牙协议栈由硬件层和软件层构成,提供通用访问Profile、服务发现应用Profile以及串口Profiles等丰富功能,确保不同设备间的良好互操作性。 3. **脉冲宽度调制调光**:脉冲宽度调制(PWM)是一种高效能的调光方式,通过调节脉冲宽度来控制LED的亮度。 当PWM频率超过200Hz时,人眼无法察觉明显的闪烁现象。 占空比指的...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值