Sloppy's Blog

Cocos2d-x Lua添加自定义回调方法,配置自定义的manual方法

在cocos2d-x Lua开发过程中,有时候会遇到自己的类需要调用Lua的方法,也就是说在c++类文件中,执行Lua的方法,可是直接在c++类里,设置LUA_FUNCTION回调方法,会导致genbindings.py出现error,这主要是由于需要引用lua.h文件,象下面这样(基于上篇的lua调用c++编译):

添加新的自定义类文件

新建CESprite.h,CESprite.cpp文件,新建内容如下:

// 添加头文件
class CESprite :public cocos2d::Sprite {
public:
    static CESprite* createWithData(const std::string& file);
    virtual void onEnter();
};
CESprite.cpp:
// 添加头文件 "CESprite.h"
// 添加头文件"scripting/lua-bindings/manual/CCLuaEngine.h"

using namespace cocos2d;

CESprite* CESprite::createWithData(const std::string& file) {
    CESprite* sp = new CESprite();
    sp->initWithFile(file);
    sp->autorelease();
    return sp;
}

void CESprite::onEnter() {
    Sprite::onEnter();
    // 执行回调
}

添加Lua回调方法

修改代码如下:

class CESprite :public cocos2d::Sprite {
public:
    static CESprite* createWithData(const std::string& file);
    virtual void onEnter();
    void setLuaHandler(LUA_FUNCTION handler);
private:
    LUA_FUNCTION handler;
};
运行genbindings.py,报错,出现lua.h找不到,可能有的朋友们,尝试将LUA_FUNCTION改成int,genbindings.py此时也能成功,但是运行后会出现nil value错误,Lua下面这样的调用:
local function cpp_call(msg)
    print("cpp_call")
    print(msg)
end
local sp = CESprite:createWithData("res/diamond3.png")
sp:setLuaHandler(cpp_call)

运行报错,怎么办?修改生成的lua_coolexp_auto.cpp里的setLuaHandler方法把arg0的获取修改成这样:
LUA_FUNCTION arg0 = toluafix_ref_function(tolua_S, 2, 0);运行,成功,并获取预期结果,可是还有问题,每个都会自动生成,每次都要去个性,太麻烦了,有没有更好的解决方法呢?答案是有,我们编写自己的manual,这里面我们可以参考cocos2d_manual.cpp.

添加动态的Lua方法,新建自己的lua_coolexp_manual.hpp文件

  • 去掉设置setLuaHandler的回调方法
    class CESprite :public cocos2d::Sprite {
    public:
      static CESprite* createWithData(const std::string& file);
      virtual void onEnter();
    };
    

添加执行回调Lua方法:
CESprite.cpp:

// 添加头文件 "CESprite.h"
// 添加头文件"scripting/lua-bindings/manual/CCLuaEngine.h"

using namespace cocos2d;

CESprite* CESprite::createWithData(const std::string& file) {
    CESprite* sp = new CESprite();
    sp->initWithFile(file);
    sp->autorelease();
    return sp;
}

void CESprite::onEnter() {
    Sprite::onEnter();
    // 执行回调
    LUA_FUNCTION handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM);
    if (handler != 0) {
        // 第一种调用方法
        cocos2d::CommonScriptData data(handler, "Hello Lua");
        cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data);
        cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent);
        // 第二种调用方法
        cocos2d::LuaEngine::getInstance()->getLuaStack()->clean();
        cocos2d::LuaEngine::getInstance()->getLuaStack()->pushString("From CPP call lua");
        cocos2d::LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 1);
        cocos2d::LuaEngine::getInstance()->getLuaStack()->clean();
    }
}
Lua的文件,就是上面的不变,可以添加在MainScene.lua里 * 在scripting目录下添加lua_coolexp_manual.hpp,lua_coolexp_manual.cpp文件,文件参考下载[@下载参考文件](data/lua_coolexp_manual.zip),具体的内容就不说明了。应该都能看得懂 * 最后在AppDelegate.cpp添加如下代码,注意顺序不要错了
 //register custom function
//LuaStack* stack = engine->getLuaStack();
register_all_coolexp(stack->getLuaState()); // 第一步
register_all_coolexp_manual(stack->getLuaState());// 第二步
  • 项目结构如下:
    HelloLuaGame