zoukankan      html  css  js  c++  java
  • cocos2dx-3.x 导出自定义类到 lua 过程详解

    转载请注明出处:http://www.cnblogs.com/Ray1024

    一、简介

    最近正在学习cocos2d中的lua游戏开发,因为lua开发的热更新特性,大家开发游戏好像都会优先选择lua作为开发语言。

    但是遇到一个问题,用lua写一些简单的程序没什么问题,但是一旦需要一个复杂的类,在lua中直接写就感觉有些吃力。所以想到,可以把游戏开发中比较复杂的模块使用c++完成,然后导出到lua,让lua可以轻松调用。

    我从头到尾完整地完成了cocos2dx-3.x中自定义类的导出过程,在网上查了好多资料,也碰到了很多错误,然而网上关于这块的文章比较零散,如果有初学者使用的话得费半天劲才能找全。所以我在这篇文章中详细地介绍整个过程,并将过程中容易出现的问题和解决方法列举出来,供大家参考。

    二、过程详解

    2.1 环境配置(windows环境下)

    注意:安装时全部选择32位版本,否则会发生无法预料的错误。
     
    首先,默认我们的cocos2dx-3.x已经安装完成(这篇文章中,我是用的是cocos2dx-3.3版本),接下来是我们的环境配置:
      a.下载python2.7.3版本,将安装路径例如(C:Python27)添加到环境变量"Path"中;
      b.下载并安装pyyaml
      c.下载 pyCheetah解压缩到python的以下路径 "C:Python27Libsite-packages";
      d.确保已经安装了android-ndk-r9b,不懂这个的请点击此处查看配置方法;
      e.设置 NDK_ROOT 的环境变量。
    这样,环境配置就完成了。
     

    2.2 写C++类

    我测试用的是cocos2d-x-3.3 estslua-empt-testprojectClassesHelloWorldScene.cpp。

    2.3 写一个导出的python脚本

    1)进入目录cocos2d-x-3.3 ools olua,复制一份genbindings.py,命名为genbindings_myclass.py
    2)把生成目录制定到咱工程里去,打开genbindings_myclass.py把

    output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root
    

    改成 

    output_dir = '%s/tests/lua-empty-test/project/Classes/auto' % project_root
    

    3)修改命令参数,把

    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'), 
                        }
    

    改成

    cmd_args = {'myclass.ini' : ('myclass', 'lua_myclass_auto') }
    

    2.4 写myclass.ini文件

    我们接下来写myclass.ini文件,拷贝一份cocos2dx_spine.ini改名,修改成如下内容:

    [myclass]
    # the prefix to be added to the generated functions. You might or might not use this in your own
    # templates
    prefix = myclass
      
    # 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 =
      
    android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/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/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/ui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s
      
    cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
      
    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/tests/lua-empty-test/project/Classes/HelloWorldScene.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 = HelloWorld
      
    # 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 =
      
    # base classes which will be skipped when their sub-classes found them.
    base_classes_to_skip = Ref ProcessBase
      
    # 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

    改的时候要注意这些行:

    [myclass]
    prefix = myclass
    target_namespace =
    headers = %(cocosdir)s/tests/lua-empty-test/project/Classes/HelloWorldScene.h
    classes = HelloWorld
    skip =
    abstract_classes =
    

    2.5 运行python脚本

    下面要自动生成代码了,打开命令行工具,cd到cocos2d-x-3.3 ools olua下,敲入

    python genbindings_myclass.py
    

    回车运行。如果前面没问题的话你会在cocos2d-x-3.3 estslua-empty-testprojectClasses多了一个文件夹auto。

    如果生成成功,那么恭喜你已经越过了难度最大、陷阱最多的地方。如果出现错误,那么很可能是你第一部分的环境配置有问题。

    注意:如果出现错误“dos2unix 既不是内部或外部命令,也不是可运行的程序”这样的错误,我的解决方法是,把自己从网上下载的dos2unix.exe文件放在C:WindowsSystem32这个文件夹底下,再重新运行脚本,就发现错误没有了。如果还不行,可以配置环境变量里的path,使之指向C:WindowsSystem32目录。dos2unix.exe的下载目录:http://pan.baidu.com/s/1kTghHzD。

    2.6 把自定义类的module加入lua

    然后把里面生成lua_myclass_auto.cpp和lua_myclass_auto.hpp加入工程中。

    把我们生成的个module在脚本引擎初始化的时候加入lua。编辑AppDelegate.cpp,包含lua_myclass_auto.hpp头文件,在

    LuaEngine* engine = LuaEngine::getInstance();
    

    后面加入

    register_all_myclass(engine->getLuaStack()->getLuaState());
    

    2.7 编译运行

    编译运行。这样HelloWorld这个类就被导出到lua了。

    2.8 导出成功,在lua中使用
    这样整个导出过程就完成了,我们就可以在lua中使用自定义类了。

    这样我们就大功告成了!

  • 相关阅读:
    linux驱动开发学习一:创建一个字符设备
    如何高效的对有序数组去重
    找到缺失的第一个正整数
    .NET不可变集合已经正式发布
    中国人唯一不认可的成功——就是家庭的和睦,人生的平淡【转】
    自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
    ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误
    自己动手搭建 Redis 环境,并建立一个 .NET HelloWorld 程序测试
    ServiceStack 介绍
    一步一步实战扩展 ASP.NET Route,实现小写 URL、个性化 URL
  • 原文地址:https://www.cnblogs.com/Ray1024/p/6202778.html
Copyright © 2011-2022 走看看