Cocos2d-x 3.1 Lua Binding

Cocos2d-x 3.1 Lua Binding

参考:http://www.cocos2d-x.org/docs/manual/code-ide/binding-custom-class-to-lua/en

添加需要绑定的C++类

在xcode中,把my文件夹拖到cocos2d_libs.xcodeproj中

HNLuaTest.h

//
//  HNLuaTest.h
//  cocos2d_libs
//
//  Created by Eleven Chen on 14-8-5.
//
//

#ifndef __cocos2d_libs__HNLuaTest__
#define __cocos2d_libs__HNLuaTest__

#include "cocos2d.h"
#include <string>

class Test : public cocos2d::Ref
{
public:

    static std::string helloMsg();

    static Test* create();

    bool init();
    static cocos2d::Vec2 left();
};

#endif /* defined(__cocos2d_libs__HNLuaTest__) */

HNLuaTest.cpp

//
//  HNLuaTest.cpp
//  cocos2d_libs
//
//  Created by Eleven Chen on 14-8-5.
//
//

#include "HNLuaTest.h"
using namespace cocos2d;

std::string Test::helloMsg()
{
    return "Hello from  HNLuaTest::helloMsg()";
}

Test* Test::create()
{
    return new Test();
}

bool Test::init()
{
    return true;
}

Vec2 Test::left()
{
    return Vec2(0, 0);
}

编写ini文件

进入到tolua目录:$(PROJECT_ROOT)/frameworks/cocos2d-x/tools/tolua

在之前先看看README文件,并安装好环境。

README文件中提到必须要用android ndk r9b来编译,因为编译的时候用到了C++ std 4.7的头文件,而r9b包含了4.7,我用的是r9d,只有4.6和4.8。我把*.ini文件里面的4.7改成4.8来编译。

新建一个cocos2dx_custom.ini文件,然后从其他文件里面copy一份代码过来修改,代码里面每一个设置都有详细的注释。

clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_custom

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = cc

# the native namespace in which this module locates, this parameter is used for avoid conflict of the same class name in different modules, as "cocos2d::Label" <-> "cocos2d::ui::Label".
cpp_namespace = 

android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_flags = -D_SIZE_T_DEFINED_ 

clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11

cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android

cocos_flags = -DANDROID

cxxgenerator_headers = 

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 

# what headers to parse
headers =  %(cocosdir)s/cocos/my/HNLuaTest.h

# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = Test.*

# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.

skip = 

rename_functions = 

rename_classes =

# for all class names, should we remove something when registering in the target VM?
remove_prefix = 

# classes for which there will be no "parent" lookup
classes_have_no_parents = Test

# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =

# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes = 

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are ‘yes‘ or ‘no‘.
script_control_cpp = no

编写genbindings.py

为了方便,每次绑定时不需要生成cocos2d-x的绑定代码,新建一个genbindings_custom.py文件,然后复制genbindings.py的代码过来,把下面的地方:

cmd_args = {‘cocos2dx.ini‘ : (‘cocos2d-x‘, ‘lua_cocos2dx_auto‘),                     ‘cocos2dx_extension.ini‘ : (‘cocos2dx_extension‘, ‘lua_cocos2dx_extension_auto‘),                     ‘cocos2dx_ui.ini‘ : (‘cocos2dx_ui‘, ‘lua_cocos2dx_ui_auto‘),                     ‘cocos2dx_studio.ini‘ : (‘cocos2dx_studio‘, ‘lua_cocos2dx_studio_auto‘),                     ‘cocos2dx_spine.ini‘ : (‘cocos2dx_spine‘, ‘lua_cocos2dx_spine_auto‘),                     ‘cocos2dx_physics.ini‘ : (‘cocos2dx_physics‘, ‘lua_cocos2dx_physics_auto‘),                     ‘custom.ini‘: (‘custom‘, ‘lua_custom_auto‘),                     ‘cocos2dx_custom.ini‘ : (‘cocos2dx_custom‘, ‘lua_cocos2dx_custom_auto‘),                     }

改为

cmd_args = {‘cocos2dx_custom.ini‘ : (‘cocos2dx_custom‘, ‘lua_cocos2dx_custom_auto‘),                     }

运行genbindings_custom.py

./genbindings_custom.py

生成的代码在 cocos/scripting/lua-bindings/auto里面

mac和ios的集成

  • 把生成的hpp和cpp拖到cocos2d_lua_bindings.xcodeproj/auto中

  • 在cocos2d_lua_bindings.xcodeproj 的Build Settings中设置头文件搜索,添加my

Android集成

  • my文件夹中添加Android.mk文件,如下内容
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := cocos_custom_static

LOCAL_MODULE_FILENAME := libmy

LOCAL_SRC_FILES := HNLuaTest.cpp

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)./

LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)./

LOCAL_CFLAGS += -Wno-psabi
LOCAL_EXPORT_CFLAGS += -Wno-psabi

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static

include $(BUILD_STATIC_LIBRARY)

$(call import-module,.)
  • 打开lua-bindings文件夹的Android.mk文件,添加以下内容

注册到Lua

修改AppDelegate.cpp

//register custom function
    //LuaStack* stack = engine->getLuaStack();
    //register_custom_function(stack->getLuaState());
    LuaStack *stack = engine->getLuaStack();
    auto L = stack->getLuaState();
    if (L)
    {
        lua_getglobal(L, "_G");
        register_all_cocos2dx_custom(L);
        lua_settop(L, 0);
    }

#if (COCOS2D_DEBUG>0)
    if (startRuntime())
        return true;
#endif
    engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str());
    return true;

这里不能按照原本代码注释的方法那样做,那样会出错。

而且都是tolua_module这个函数里面的lua_rawget(L,-2);这一行出错。

原因是:

  1. auto engine = LuaEngine::getInstance();
  2. _defaultEngine->init();
  3. executeScriptFile(“Deprecated.lua”);
  4. _stack->clean();
  5. lua_settop(_state, 0);

LuaEngine初始化的时候会运行3个lua文件,把stack给清空了。

tolua_module函数中,lua_pushstring(L,name);后,栈只有一个元素,所以lua_rawget(L,-2);就会出错。

只需要把_G放到栈中,再运行register_all_cocos2dx_custom(L);,如果模块不在_G中,就添加到_G中,就可以全局访问了。

cocos code ide build custom runtime

测试

-- test custom
 local msg = cc.Test:helloMsg()
 print(msg)

输出

Cocos2d-x 3.1 Lua Binding

时间: 2024-12-15 06:49:32

Cocos2d-x 3.1 Lua Binding的相关文章

cocos2d-x LUA Binding实现C++里访问LUA的自定义对象

LUA Binding比JSBinding要简单,无论是使用脚本自动绑定还是手动写绑定代码,都能很轻松实现在LUA访问C++的类和对象.但如果想在C++里访问LUA里的自定义类和对象,则需要再自己修改一下C++的代码了. 应用场景: 1.  假设在LUA里有一个类MyLayer,继承了CCLayer,并添加了a,b,c,d这4个属性. 2.在LUA里,创建一个MyLayer的实例对象,并添加到当前的Scene中,然后通过Scene.getChildByTag方法拿出这个MyLayer的实例对象时

cocos2d的-X- luaproject的LUA脚本加密

2014/1/26 更新 近期又发现了一个非常easy的方法,事实上coco2dx已经给我们提供设置loader的方法. 注意:有个局限性,在非android平台下调用pEngine->executeScriptFile是不调用loader的,仅仅有require这样的才会调用loader.也就是说你直接executeScriptFile("main.lua")这个脚本不能加密,main.lua里面require的才干加密 过程例如以下: 1.实现自己的loader(參考int

cocos2d-x + Lua接入iOS原生SDK的实现方案[转]

相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我做过项目中接入iOS原生SDK实现方案的一个总结,在这里分享给大家,希望对自己和大家的开发工作都有帮助. 在展开正文之前,先做几点说明: 1.我这里说的iOS原生SDK是指那些完全用Objective-C语言开发,为原生iOS程序设计的SDK.swift很好很强大,不过我还没用过,惭愧,不过语言终归

[原创]cocos2d-x + Lua接入iOS原生SDK的实现方案

相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我做过项目中接入iOS原生SDK实现方案的一个总结,在这里分享给大家,希望对自己和大家的开发工作都有帮助. 在展开正文之前,先做几点说明: 1.我这里说的iOS原生SDK是指那些完全用Objective-C语言开发,为原生iOS程序设计的SDK.swift很好很强大,不过我还没用过,惭愧,不过语言终归

skynet源码分析5:lua绑定之地基

前面四篇已经涵盖了skynet的c层核心,剩下的timer,socket模块本身和actor模型没什么关系,且比较独立,最后再看吧.光用skynet的c接口,是很难在这上面写业务逻辑的,所以要找一种更爽快的方式来使用.官方推荐的是lua,利用lua的协程对skynet的消息分发做了封装,使得actor之间的异步消息通信有同步一样的操作感,并且做了一些的扩展模块来方便使用.lua简洁实用的风格我个人也很钟意. 要想做一个lua binding来使用,要有两个必要条件: 根据skynet的模块契约实

cocos2d-x lua中实现异步加载纹理

原文地址:  http://www.cnblogs.com/linchaolong/p/4033118.html 前言   问题:最近项目中需要做一个loading个界面,界面中间有一个角色人物走动的动画,在显示这个loading界面的时候加载资源,项目是用cocos2d-x lua实现的,界面做出来后发现在加载资源的时候界面会卡住. 原因: 因为使用的不是异步加载,而且cocos2d-x没有绑定异步加载资源的api到lua中,其实在lua中实现不了异步. 想通过在lua中启动一个线程去加载资源

Quick-Cocos2dx-Community lua绑定,lua调用C++ 类

http://blog.csdn.net/marpools/article/details/44341021#reply 这里有篇文章,看三和四. 按上面操作,文件都不缺少的,可以直接看  2. 和 3 . 记住:player3 来打开项目, 的类格式化后,放到他的源代码路径下面, 解释生成的lua 也要放到 api下面 player3  重新生成就可以了 player3    最后打开可能会出现, a nil value. 其实,我们用cocos2d-x-3.10, D:\cocos\setu

项目用到了lua的哪些部分

昨天有位同事跟我说,我们的手游客户端(cocos2d-x lua binding)代码没有看到lua的特殊技巧,用起来跟其他语言差不多.<Programming in lua>毕竟有将近400多页,他想知道lua的语言特性都用在哪了.当其时回答不上来,现在来思考一下. 要解答他的疑问首先要解答的却是另外两个问题: 1.为什么我们的项目选用了lua? lua官网是这样介绍lua的:fast, portable, embeddable, powerful(but simple), small, f

cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++

cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值得吐槽的是.这套流程在开发中差点儿是不可避免的,而cocos2d-x居然不把它作为一个公用接口暴露给开发人员,而须要我自己动手,真是无奈. 以下以一个简单的消息分发类为样例,演示怎样完毕这一工作. MessageDispatcher.h class MessageDispather { public