cocos2d-2.1rc0-x-2.1.3使用lua

来源:互联网 发布:淘宝换主图会降权吗 编辑:程序博客网 时间:2024/06/07 00:58
需要包含的头文件:
E:\cocos2d-2.1rc0-x-2.1.3\scripting\lua\lua
E:\cocos2d-2.1rc0-x-2.1.3\scripting\lua\tolua
E:\cocos2d-2.1rc0-x-2.1.3\scripting\lua\cocos2dx_support


加入lib的链接:liblua.lib,lua51.lib



使用VSLua实现在VS里面写,调试Lua。
http://vslua.codeplex.com/
但是只支持2008,2010,不支持2012.

网上有修改过的支持2012:


实在不行还有一个高亮插件,只能高亮了:



Lua脚本里面cclog不起作用的修改:
方案1:把cocos2dx的lua库,定义一个COCOS2D_DEBUG重新编译

测试如下:


我们把lua保存为UTF-8,那么就还可以直接写中文输出了!


还有一个解决方案:
Just changed function in log.lua to CCLuaLog() and it’s star to work



讲解下(下面就是一个简单的例子):

-- for CCLuaEngine traceback
-- 也是异常的回调接口
function __G__TRACKBACK__(msg)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(msg) .. "\n")
    print(debug.traceback())
    print("----------------------------------------")
end

cclog = function(...)
    print(string.format(...))
end
local CCLog = cclog
local CCLOG = cclog

local function main()

 cclog("main。。。。。");
 cclog("+++++++++++++++++++++++++++++++++++++++++++++++++++=");

 -- 操作垃圾回收器
 --[[
 collectgarbage (opt [, arg])
   功能:是垃圾收集器的通用接口,用于操作垃圾收集器
   参数:
   opt:操作方法标志
   "Stop": 停止垃圾收集器
   "Restart": 重启垃圾收集器
   "Collect": 执行一次全垃圾收集循环
   "Count": 返回当前Lua中使用的内存量(以KB为单位)
   "Step": 单步执行一个垃圾收集. 步长 "Size" 由参数arg指定 (大型的值需要多步才能完成),
   如果要准确指定步长,需要多次实验以达最优效果。如果步长完成一次收集循环,将返回True
   "Setpause": 设置 arg/100 的值作为暂定收集的时长
   "Setstepmul": 设置 arg/100 的值,作为步长的增幅(即新步长=旧步长*arg/100)
 --]]
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)

    local visibleSize = CCDirector:sharedDirector():getVisibleSize()
    local origin = CCDirector:sharedDirector():getVisibleOrigin()


 local layer = CCLayer:create();
 local image = CCSprite:create("farm.jpg");
 layer:addChild(image);
 image:setPosition(ccp(100,100));

 local scene = CCScene:create();
 scene:addChild(layer);

 CCDirector:sharedDirector():runWithScene(scene);

end


-- pcall的函数,类似于try-catch是一种安全的调用方式
-- 如果没有异常和错误,pcall返回true和调用返回的任何值;否则返回nil加错误信息
-- 但是pcall返回的时候堆栈就没了,于是外界是不能打印堆栈的
--
-- xpcall就是完成这个的
-- 有异常就先调用异常处理函数 __G__TRACKBACK__
xpcall(main, __G__TRACKBACK__)



cocos2dx Lua的执行流程:



关于Lua的loader:

从 Lua 5.1 以后,Lua 有了标准的模块管理库。所以所有的模块加载都是通过 require 来完成。 require 的设计是颇具扩展性的,它会从若干个定义好的 loader 中逐个尝试加载新的模块。系统库中提供了四个 loader ,分别实现已加载模块,Lua 模块,和 C 扩展模块(用了两个 loader 来实现 C 扩展模块的加载)。这些 loader 以 CFunction 的形式放在 require 的环境中的一个 table 里。

如果我们想改变 lua 模块的加载形式,只需要替换或增加一个新的 loader 就可以了。

要做的只需要模仿 loadlib.c 中的 loader_Lua 函数做一个自己的实现,比如在我们的项目中,就允许从自定义格式数据包中,加载一个被加密过的 Lua 代码文件。然后写几行 C 代码,获得 require 的环境(使用 lua_getfenv ),然后取出其中 "loaders" 这个 table ,把新的自定义 loader 插入到 index 2 的地方。

具体的代码就不详述了,仔细阅读一下 ll_require 的实现(在 loadlib.c 中)就很容易明白。我们的整个工作从分析到实现没有超过两个小时,这真是得益于 Lua 良好的设计啊 :D 甚至如果你想从一个网络连接的数据流中加载 Lua 模块,或是通过 http/ftp 协议下载,也是行的通的吧。



lua里面使用我们C++层定义的类:
所以,如果想把我们的暴露给lua,直接根据上面分析的流程,直接在tolua_Cocos2d_open里面添加注册就是了。
可以用tolua(一个小工具,提供了很多方便方法),或者直接注册。

直接看用tolua工具注册:
E:\cocos2d-2.1rc0-x-2.1.3\tools\tolua++里面的README有简单的讲解。
比如使用BaseSprite类(这个类使用了ResourceManager这个类),

第一步:写tolua工具的配置文件(就是.pkg/或者.tolua文件,比如CCAction.pkg),写法其实就是头文件的修改版而已。
详细的步奏见:
http://cn.quick-x.com/?p=235
http://xiaominghimi.blog.51cto.com/2614927/1173220
我们要像Lua暴露出BaseSprite的方法,于是就直接修改BaseSprite.h到BaseSprite.pkg

第二步:拷贝到E:\cocos2d-2.1rc0-x-2.1.3\tools\tolua++
然后把pkg添加到Cocos2d.pkg里面。这样build的时候才会把这个pkg加进去


第三步:根据情况修改basic.lua
因为lua有自己的内存管理,但是CCObject都是自己管理内存的,所以我们继承自CCObject的所有子类都应该告诉Tolua。
不然会内存泄露。

注册与否的区别(一个是tolua_pushusertype,一个是toluafix_pushusertype_ccobject):

第三步:执行build.bat/[.sh]
脚本的内容是:
tolua++ -L basic.lua -o "../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp" Cocos2d.pkg
意思是:在执行之前先执行basic.lua脚本,然后再根据Cocos2d.pkg指定的各个pkg,执行生成LuaCocos2d

到对应的目录中查看就可以看到新修改好的LuaCocos2d

我们查看
LuaCocos2d的tolua_Cocos2d_open 函数后面,就添加上了我们的代码:
  tolua_cclass(tolua_S,"BaseSprite","BaseSprite","CCSprite",NULL);
  tolua_beginmodule(tolua_S,"BaseSprite");
   tolua_function(tolua_S,"create",tolua_Cocos2d_BaseSprite_create00);
   tolua_function(tolua_S,"create",tolua_Cocos2d_BaseSprite_create01);
   tolua_function(tolua_S,"getFileName",tolua_Cocos2d_BaseSprite_getFileName00);
   tolua_function(tolua_S,"initWithFile",tolua_Cocos2d_BaseSprite_initWithFile00);
   tolua_function(tolua_S,"initWithFile",tolua_Cocos2d_BaseSprite_initWithFile01);
   tolua_function(tolua_S,"initWithFileDelay",tolua_Cocos2d_BaseSprite_initWithFileDelay00);
   tolua_function(tolua_S,"removeNode",tolua_Cocos2d_BaseSprite_removeNode00);
  tolua_endmodule(tolua_S);
就完成了注册了!!
把生成的LuaCocos2d.cpp拷贝到我们项目里就是了。然后添加好头文件就是了。

上面的basic.lua是一些其他的逻辑,比如LUA_FUNCTION类型的处理(LUA_FUNCTION用于在C++声明lua的函数)。

第四步:测试
注意,这里修改的是scripting/lua/cocos2dx_support/LuaCocos2d.cpp,所以,以后新建的lua项目都用的这个这个文件了。

成功!

0 0