cocos2d-lua09apk打包发布&C++注册到Lua

来源:互联网 发布:apache derby 编辑:程序博客网 时间:2024/05/22 06:28



 将Lua项目在Android平台发布
1。使用CocosCodeIDE完成游戏的开发
2。安装以下软件
   2.1 Android sdk
   2.2 Eclipse +adt插件
   ADT
   2.3 Android NDK
   2.4 Ant
   2.5 Java SDK
3。设置环境变量
   ANDROID_SDK_ROOT 
   ANT_ROOT
   NDK_ROOT
4。安装cocos引擎
  python setup.py
5。创建一个Cocos Lua项目
 cocos new -p com.game.test -l lua -d d: luagame0728


6.在VS2013中完成项目调试
7.在Eclipse中打开项目
8。设置项目的SDK
9。拷贝 
    项目目录\frameworks\cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib
  到
    项目目录\frameworks\runtime-src\proj.android\src\org\cocos2dx
10.修改
项目目录\frameworks\runtime-src\proj.android\jni\Android.mk
  设置要编译的Cpp文件



[custom_api]
  
# prefix会被添加到生成的函数.你也可以选择不添加这个到你的模板
prefix = custom_api
  
# 所有的类都会嵌入到这个命名空间
target_namespace = my
  
# 类所在的路径,如果有多个,用空格隔开
headers = %(cocosdir)s/../runtime-src/Classes/PanZoomLayer.h
  
# 需要注册的类,如果有多个,用空格隔开
classes = PanZoomLayer
  
# 不提供给Lua的public成员函数
skip = PanZoomLayer::[onTouchesBegan onTouchesMoved onTouchesEnded init onEnter onExit update]
  
# 这些全空就OK
rename_functions =
rename_classes = 
remove_prefix = 
classes_have_no_parents = 
base_classes_to_skip =
abstract_classes = 
script_control_cpp = no


cocos2dx3.0rc导出自定义类到lua的方法详细步骤   






以前要导出c++类到lua,就得手动维护pkg文件,那简直就是噩梦,3.0以后就会感觉生活很轻松了。


下面我就在说下具体做法。
1、安装必要的库和工具包,以及配置相关环境变量,
请按照cocos2d-x-3.0rc0\tools\tolua\README.mdown说得去做,不做赘述。


2、写c++类(我测试用的是cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes\HelloWorldScene.cpp)


3、写一个生成的python脚本,你不会写,没关系,我们会照猫画虎
   1)进入目录cocos2d-x-3.0rc0\tools\tolua,
复制一份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') }
    4)这时你可能问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 =
4、下面要自动生成代码了,打开命令行工具,cd到
cocos2d-x-3.0rc0\tools\tolua下,敲入
python genbindings_myclass.py
回车运行。
如果前面没问题的话你会在cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes
多了一个文件夹auto,
然后把里面生成lua_myclass_auto.cpp和lua_myclass_auto.hpp加入拽如工程


5、把我们生成的个module在脚本引擎初始化的时候加入lua。
编辑AppDelegate.cpp,包含lua_myclass_auto.hpp头文件,在
LuaEngine* engine = LuaEngine::getInstance();
后面加入
register_all_myclass(engine->getLuaStack()->getLuaState());


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


测试------------------------------------------------
打开hello.lua,编辑local function main()这个函数
把前面改成
local function main()
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)


    local hello = HelloWorld:create()
    local sceneGame = cc.Scene:create()
    sceneGame:addChild(hello)
    cc.Director:getInstance():runWithScene(sceneGame)


    if(1==1) then
        return
    end
……
……






copy一个。。。哈哈哈!!!


首先是将C++函数绑定进LUA,也就是从LUA中调用C++的函数

[cpp] view plaincopy

1. static int httpSend(lua_State*L)  

2. {  

3.     const char * url = lua_tostring(L, 1);  

4.       

5.     return 0; //返回给lua几个参数 

6. }

7. 

8.  

首先,先声明一个static的函数,返回值必须是int参数只有一个是lua_State*L

然后AppDelegate::applicationDidFinishLaunching()函数中加入

   lua_register(L, "APhttpSendMethod", httpSend);

这个是将C++函数注册到LUA虚拟机中,然后在lua中可以通过APhttpSendMethod("123")调用C++的方法了

[cpp] view plaincopy

1. bool AppDelegate::applicationDidFinishLaunching()  

2. {      

3.     auto engine = LuaEngine::getInstance();  

4.     ScriptEngineManager::getInstance()->setScriptEngine(engine);  

5.     lua_State* L = engine->getLuaStack()->getLuaState();  

6.     lua_module_register(L);  

7.     lua_register(L, "APhttpSendMethod", httpSend);//这句  

8.       

9.     if (engine->executeScriptFile("src/main.lua")) {  

10.         return false;  

11.     }  

12.     return true;  

13. }  

在让lua调用的方法中,lua传入的参数是通过lua_tostring这种宏定义来获取的。

const char * url = lua_tostring(L, 1);

所有数据类型都可以通过类似于lua_tostring的方式来读取,第二个参数可以传递几个参数。

关于这块儿的知识更多详细内容可以查看Lua程序设计一书,讲解的十分清楚,我就不露怯了!

其次,返回值return 0 是表示,C++函数会返回几个返回值给lua  通过lua_pushstring来像lua返回返回值。

 

下面是C++调用LUA的函数,首先有一点需要说明,C++调用lua函数,会重新载入一次lua函数所在的文件!

[cpp] view plaincopy

1. void httpReceive()  

2. {  

3.     lua_State*  ls = cocos2d::LuaEngine::getInstance()->getLuaStack()->getLuaState();//获取lua虚拟机  

4.     std::string scriptPath=cocos2d::FileUtils::getInstance()->fullPathForFilename("httpCallback.lua");//载入lua函数所在文件  

5.     int isOpen = luaL_dofile(ls, scriptPath.c_str());//打开文件  

6.       

7.     if (isOpen != 0){  

8.         CCLOG("AppDelegate httpReceive --> Open Lua Error: %i", isOpen);  

9.         return ;  

10.     }  

11.       

12.     lua_getglobal(ls, "httpCallback");//获取lua的函数 也就是要调用的函数  

13.       

14.     lua_call(ls, 0, 0);//执行!俩参数分别是你给lua函数传入了几个参数,lua函数将返回几个参数。  

15. }

16.  

至于lua函数,非常简单,

function httpCallBack()

end

就可以了

 




再copy一个,呵呵呵!!!


使用LUA脚本开发游戏有着诸多的优势,动态更新,不需要考虑内存和数据类型等等。但是LUA脚本的安全性问题却似的许多开发者非常苦恼。

 [cpp] view plaincopy

1. cocos luacompile -s /Users/archer/Desktop/CocosPro/CocosLuaGameNetTest001/src  -d /Users/archer/Desktop/CocosPro/CocosLuaGameNetTest001/src/erc -e -k Archer -b XXTEAScript  

其中:

-s lua脚本所在路径

-d 是编译好的lua脚本存放路径(编译后的lua脚本会变成.luac不用担心原来的lua脚本文件被覆盖)

-e 表示对脚本进行加密

-k 是脚本加密的KEY

-b 是脚本加密的签名(Cocos2d通过检查是否有签名来判断脚本是否需要解密运行)

[cpp] view plaincopy

1. cocos luacompile -s ./projects/MyLuaGame/src -d ./projects/MyLuaGame/src -e -k MyLuaKey -b MyLuaSign  

然后查看帮助是:

[cpp] view plaincopy

1. cocos luacompile -h  

参数详细说明:

参数

允许的参数

例子

描述

必要

-h, --help

显示说明

-s, --src

源码路径

./projects/MyLuaGame/src

所需要编译和加密的源码的路径

-d, --dst

编译后文件路径

./projects/MyLuaGame/src

源码编译或加密后保存的路径

-e, --encrypt

允许对编译后脚本进行加密

-k, --encryptkey

任意字符串

ArcherPeng

加密所用的KEY

-b, --encryptsign

任意字符串

XXTEAScript

加密所有的签名


在对脚本编译和加密的工作完成后,我们还需要在AppDelegate中,设置下脚本解密的KEYSign

打开AppDelegate.cpp文件,大约56行位置:

[cpp] view plaincopy

1. <span style="font-size: 18px;"> </span>   auto engine = LuaEngine::getInstance();  

2.     ScriptEngineManager::getInstance()->setScriptEngine(engine);  

3.   

4.     LuaStack* stack = engine->getLuaStack();  

5.     stack->setXXTEAKeyAndSign("Archer", strlen("Archer"), "XXTEAScript", strlen("XXTEAScript"));//这里  

6.       

7.     //register custom function  

8.     //LuaStack* stack = engine->getLuaStack();  

9.     //register_custom_function(stack->getLuaState());  

10.       

11. #if (COCOS2D_DEBUG>0)  

12.     if (startRuntime())  

13.         return true;  

14. #endif  


stack->setXXTEAKeyAndSign("Archer",strlen("Archer"),"XXTEAScript",strlen("XXTEAScript"));

两个Archer的位置是KEY(即编译时的-k),两个XXTEAScript的地方是SIGN(即编译时的-b

好了就是这样,感谢大家的关注。

最后一步不要忘,移除没有加密的*.lua文件~只包含编译之后的luac就够了~

由于iphone6 5s64位架构上是不支持luajit编译的,所以只能使用lua脚本运行,不能用luajit编译后的字节码。

所以需要在 上边命令后加一行  --disable-compile  以禁止cocos工具将lua进行编译,这样就只通过xxtea加密代码,但是不编译啦~示例:

[cpp] view plaincopy

1. cocos luacompile -s /Users/archerpeng/Documents/CocosProjects/CocosProjectLuaXXteaTest/src   -d /Users/archerpeng/Documents/CocosProjects/CocosProjectLuaXXteaTest/src  -e -k Archer -b XXTEAScript --disable-compile  

如果你所用的版本没有--disable-compile  这个参数

可以下载最新版本的cocos然后拷贝一个过去,路径是:

/cocos2d-x-3.3/tools/cocos2d-console/plugins/project_compile/project_compile.py

 


1 0
原创粉丝点击