【Cocos2d-x】绑定C++自定义类到Lua

tolua++简介

tolua++工具所在目录:cocos2d-x-2.2.1\tools\tolua++, 在目录下有一个README文件,打开有关于这个工具的介绍与使用说明。

工具描述: Generating the lua<-->C bindings with tolua++, tolua++用于生成lua与C之间交互的绑定文件。


通过使用该命令生成绑定文件  :tolua++.exe -L basic.lua -o LuaCocos2d.cpp Cocos2d.pkg,新生成的LuaCocos2d.cpp文件将会覆盖旧的。

LuaCococs2d.cpp文件所在路径:cocos2d-x-2.2.1\scripting\lua\cocos2dx_support。

在LuaCocos2d.cpp文件中完成我们自定义类的注册,然后才能在Lua中使用我们C++中的自定义类。


tolua++工具的使用

环境说明:

系统:win7

工程:cocos2d-x lua工程

开发工具:vs2010


自定义类


类声明如下:SpriteFactory.h

#ifndef _SPRITE_FACTORY_H_ 
#define _SPRITE_FACTORY_H_ 

#include "cocos2d.h"

USING_NS_CC;

class SpriteFactory{
public:
	static void createSprite(CCLayer* layer);
};


#endif


类实现如下:SpriteFactory.cpp

#include "SpriteFactory.h"

void SpriteFactory::createSprite(CCLayer* layer){
	//创建一个CCLayerColor
	CCLayer* addLayer = CCLayerColor::create(ccc4(200,100,100,255));
	addLayer->setContentSize(CCSizeMake(layer->getContentSize().width/2,layer->getContentSize().height/2));
	addLayer->setPosition(ccp(layer->getContentSize().width/2,layer->getContentSize().height/2));
	//添加到目标Layer
	layer->addChild(addLayer);
} 

项目结构如下:

【Cocos2d-x】绑定C++自定义类到Lua_第1张图片


编写pkg文件


pkg文件的编写,需要遵循以下规则:

2. Writing .pkg files
    1) enum keeps the same                                                                           保持枚举类型值的定义
    2) remove CC_DLL for the class defines, pay attention to multi inherites       不要使用CC_DLL(点击查看CC_DLL详细解释
),使用多继承代替

    3) remove inline keyword for declaration and implementation                    在声明和实现中移除inline关键字
    4) remove public protect and private                                                        移除public、protect和private关键字
    5) remove the decalration of class member variable                                  移除类成员变量的定义
    6) keep static keyword                                                                             保持static关键字 
    7) remove memeber functions that declared as private or protected           移除那些声明为private或者protected的成员函数


pkg文件内容如下:SpriteFactory.pkg

class SpriteFactory{
    static void createSprite(CCLayer* layer);
};
编写好的pkg文件放到cocos2d-x-2.2.1\tools\tolua++目录下。


使用tolua++生成LuaCocos2d.cpp


1.在Cocos2d.pkg文件中包含我们自定义的pkg文件(Cocos2d.pkg文件在tolua++目录下)
【Cocos2d-x】绑定C++自定义类到Lua_第2张图片

包含自定义类头文件

【Cocos2d-x】绑定C++自定义类到Lua_第3张图片


2.解压tolua++工具

在tolua++目录下有两个压缩包分别是Mac平台下的tolua++工具和Windows平台下的tolua++工具,由于我是在Windows平台下工作的,所以解压tulua++.rar到当前目录下。

【Cocos2d-x】绑定C++自定义类到Lua_第4张图片


3.执行生成命令

在tolua++目录下有一个build.bat脚本(Windows),和一个build.sh脚本(Mac,Linux),用于生成LuaCocos2d.cpp文件。

点击build.bat脚本,当脚本执行完毕,新的LuaCocos2d.cpp文件就生成了。

【Cocos2d-x】绑定C++自定义类到Lua_第5张图片


包含自定义类的头文件目录

【Cocos2d-x】绑定C++自定义类到Lua_第6张图片


在包括头文件的时候,我们可能会遇到 " Error: 无法打开源文件 "的情况,解决办法如下:

右键liblua,选择属性—配置属性—C/C++目录—常规,在附加包含目录里添加我们自定义类文件所在目录,用";"隔开,最后点击确定,错误就消失了

【Cocos2d-x】绑定C++自定义类到Lua_第7张图片

注意:

1.在添加包含目录时,建议使用相对路径,如:$(ProjectDir)..\..\..\..\Classes\ui;($ProjectDir表示当前工程liblua的根目录)

2.附加包含目录必须是目标头文件所在目录,不可以是其父目录


在Lua中使用C++自定义类


这里我就直接在cocos2d-x lua项目Resource目录下的hello.lua脚本中使用自定义的SpriteFactory,在背景层上添加一个宽高为该背景层一半的CCLayerColor

【Cocos2d-x】绑定C++自定义类到Lua_第8张图片

运行效果:

【Cocos2d-x】绑定C++自定义类到Lua_第9张图片


更好的绑定方法


这种绑定方法不修改引擎的LuaCocos2d.cpp文件,通过绑定脚本生成自定义的绑定代码,然后在CCLuaStack中调用绑定方法把C++自定义类绑定到Lua。


1.复制tolua++目录下的build.bat,重命名为,如:build_My.bat(名称自己定义,我这里就都用My了)。

修改文件内容如下:

tolua++ -L basic_my.lua -o "../../scripting/lua/cocos2dx_support/LuaMy.cpp" My.pkg
pause


2.复制tolua++目录下的basic.lua,并重命名为,如:basic_my.lua

在CCObjectTypes中增加绑定类名称,比如:

local CCObjectTypes = {
    "AsynResLoader",
    "AsynTaskHandler",
}

CCObjectTypes是一个要绑定到Lua的类型名称数组,要绑定的类必须是直接或间接继承CCObject的类。


修改open函数名称

【Cocos2d-x】绑定C++自定义类到Lua_第10张图片

把tolua_Cocos2d_open修改为tolua_My_open


3.编写pkg文件

包含头文件和自定义类的pkg文件

$#include "LuaMy.h"
$#include "AsynResLoader.h"
$#include "AsynTaskHandler.h"

$pfile "AsynResLoader.pkg"
$pfile "AsynTaskHandler.pkg"

4.在CCLuaStack的init方法中调用tolua_My_open函数注册自定义类(liblua项目中记得包含自定义类头文件目录)

LuaMy.h头文件代码如下:

#ifndef __LUAMY_H_
#define __LUAMY_H_

#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif

TOLUA_API int tolua_My_open(lua_State* tolua_S);

#endif
只有一个open函数,文件放在cocos2d-x-2.1.5\scripting\lua\cocos2dx_support目录下。


在CCLuaStack中引入LuaMy.h,并调用open函数。

bool CCLuaStack::init(void)
{
    m_state = lua_open();
    luaL_openlibs(m_state);
    tolua_Cocos2d_open(m_state);
    //调用open函数
    tolua_My_open(m_state);
    toluafix_open(m_state);

    // Register our version of the global "print" function
    const luaL_reg global_functions [] = {
        {"print", lua_print},
        {NULL, NULL}
    };
    luaL_register(m_state, "_G", global_functions);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
    CCLuaObjcBridge::luaopen_luaoc(m_state);
#endif
    
    register_all_cocos2dx_extension_manual(m_state);
    
    // add cocos2dx loader
    addLuaLoader(cocos2dx_lua_loader);

    return true;
}


最后,点击build_My.bat,就会生成LuaMy.cpp到cocos2d-x-2.1.5\scripting\lua\cocos2dx_support目录下了。重新编译,绑定完成!

你可能感兴趣的:(Cocos,Cocos2d-x游戏开发总结)