Cocos2d-x 3.2 Lua调用自定义C++类

1.环境

  • 系统:Windows 7 64位
  • Cocos2d-x:3.2
  • python:2.75 32位
  • NDK:android-ndk-r9b或android-ndk-r9d,需要配置环境变量:NDK_ROOT
  • pyyaml:PyYAML-3.10.win32-py2.7.exe 安装到 ..\Python27\Lib\site-packages
  • pyCheetah:Cheetah.zip 解压到 ..\Python27\Lib\site-packages

2.自定义C++类

路径:我保存在..\cocos2d-x-3.2\cocos\my\

// CustomClass.h
#ifndef __CUSTOM__CLASS
#define __CUSTOM__CLASS
#include "cocos2d.h"
namespace cocos2d {
class CustomClass : public cocos2d::Ref
{
public:
    CustomClass();
    ~CustomClass();
    static cocos2d::CustomClass* create();
    bool init();
    CREATE_FUNC(CustomClass);
};
} //namespace cocos2d
#endif // __CUSTOM__CLASS
// CustomClass.cpp
#include "CustomClass.h"
USING_NS_CC;
CustomClass::CustomClass(){
}
CustomClass::~CustomClass(){
}
bool CustomClass::init(){
    return true;
}
std::string CustomClass::helloMsg() {
    return "Hello from CustomClass::sayHello";
}

3.自定义ini文件

路径:..\cocos2d-x-3.2\tools\tolua\

可复制目录下的某个ini文件作为模板,我用了:cocos2dx_spine.ini

主要需要修改以下参数配置:

  • [cocos2dx_spine]
  • prefix = cocos2dx_spine
  • target_namespace = sp
  • headers = %(cocosdir)s/cocos/editor-support/spine/spine-cocos2dx.h
  • classes = Skeleton SkeletonAnimation

我这里的设置是:

  • [cocos2dx_custom]
  • prefix = cocos2dx_custom
  • target_namespace = my
  • headers = %(cocosdir)s/cocos/my/CustomClass.h
  • classes = CustomClass

4.修改genbindings.py脚本

路径:..\cocos2d-x-3.2\tools\tolua\genbindings.py

找到cmd_args项,增加:

'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom'), \

可用#注释掉其它的ini文件引用

5.运行genbindings.py脚本

路径:..\cocos2d-x-3.2\tools\tolua\genbindings.py

在命令提示符中进入脚本所在目录,执行:

python genbindings.py

完成后可在..\cocos2d-x-3.2\cocos\scripting\lua-bindings\auto\中找到生成的文件

6.运行工程

  • 用visual studio打开..\cocos2d-x-3.2\build\cocos2d-win32.vc2012.sln,设置lua-empty-test为启动项目。
  • 将..\cocos2d-x-3.2\cocos\my\下的自定义类添加到项目lua-empty-test的Classes中
  • 将生成的C++的桥接文件添加到项目liblua的auto下
  • 对liblua项目右键,在属性 - 配置属性 - C/C++ - 常规 - 附加包含目录中加入生成文件路径..\cocos2d-x-3.2\cocos\my\
  • 编辑lua-empty-test的入口类AppDelegate.cpp:
#include "cocos2d.h"
#include "AppDelegate.h"
#include "audio/include/SimpleAudioEngine.h"
#include "base/CCScriptSupport.h"
#include "CCLuaEngine.h"

USING_NS_CC;
using namespace CocosDenshion;

AppDelegate::AppDelegate()
{
    // fixed me
    //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
}

AppDelegate::~AppDelegate()
{
    // end simple audio engine here, or it may crashed on win32
    SimpleAudioEngine::getInstance()->end();
    //CCScriptEngineManager::destroyInstance();
}
bool AppDelegate::applicationDidFinishLaunching()
{
    // register lua engine
    LuaEngine* engine = LuaEngine::getInstance();
    ScriptEngineManager::getInstance()->setScriptEngine(engine);
    
    //The call was commented because it will lead to ZeroBrane Studio can't find correct context when debugging
    //engine->executeScriptFile("src/hello.lua");
    //增加以下5句
    LuaStack* stack = engine->getLuaStack();
    lua_State* state = stack->getLuaState();
    lua_getglobal(state, "_G");
    register_all_MyClass(stack->getLuaState());
    lua_pop(state, 1);

    engine->executeString("require 'src/hello.lua'");
    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    Director::getInstance()->stopAnimation();
    SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    Director::getInstance()->startAnimation();
    SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
  • 在lua中引用自定义的C++类

路径:..\cocos2d-x-3.2\tests\lua-empty-test\src\

打开hello.lua,在main方法中加入以下代码:

    local test = my.CustomClass:create()
    print("==================== " .. test:helloMsg())
  • 执行

回到visual studio,开始执行,搞掂。