Cocos2dx-Lua与C++混合使用

本文转载于http://www.cnblogs.com/zisou/p/cocos2dx-lua1.html

上面一个问题我觉得在我们使用Lua之前需要深入思考的,Lua有何优点?缺点又是什么?先找准自己的项目定位

在什么时候使用是很必要的;

经过自己一番摸索之后有如下结论:

优点:

1,嵌入式脚本开发可以跳过平台市场进行独立的游戏资源更新;

2,在使用Lua开发能降低在使用C++中得指针引用报错,nil类型问题;

3,可以使用Lua表结构来完成面向对象;

还有一个项目定位的问题,那就是开发游戏,用全Lua,还是C++绑定Lua呢?

全Lua:

如果使用全Lua,我建议完全使用Cocos2d-x触控官方收购了成都的Quick-Cocos2dx!用Quick开发优势就一个

字!快!官方提供的框架(quicklua包)目前是2.2版本(3.0以后也会同步),以后我会补上配置Quick开发的环境;

C++绑定Lua:

在项目定位中,只有一部分模块(活动等)需要使用Lua开发,那就必须半路出家,从中途绑定上Lua,进行C++和

Lua的交叉开发,这种绑定开发是比较流行的,因为C++能利用Lua的优势实现自更新,Lua也能依赖C++借助它的

底层开发能力完成相对复杂的开发;

上面对Lua的使用做了个概述,下面直接进行重要环节了,将会在xcode和eclipse上实现cocos2dx+lua!

本篇可能有点长,自带小板凳,瓜子观看;

———————————————————————————————————————————————————

使用版本Cocos2dx2.2版本,

Xcode中手动绑定 Cocos2dx+lua:

1,首先新建一个cocos2dx新工程,怎么建都可以,最终能再Xcode运行起来都行;

Cocos2dx-Lua与C++混合使用_第1张图片

2,新建好后在libs文件夹下面添加Lua的libs包;

Cocos2dx-Lua与C++混合使用_第2张图片

这个是我用xcode新建出来的Lua项目,里面自带了一个包Lua文件夹;

也可以使用cocos2dx自带:

Cocos2dx-Lua与C++混合使用_第3张图片

对比后发现用了4个目录,cocos2dx_support,lua,luajit,tolua

Cocos2dx-Lua与C++混合使用_第4张图片

3,添加完成之后点Run会报错,是因为缺少CocoStudio这个库,如果你项目以后要使用CocoStudio那就再把库导进来,如果不用

那就直接注释掉CocoStudio相关的就可以跑起来了!

4,OK跑起来之后,我们就可以使用Lua脚本了,我们先简单写一个测试的(功能为在C++加载一个CClayer,CClayer中有一个

背景精灵图片)

(一)首先我们需要先把lua脚本代码写出来

testlua.lua

-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(msg) .. "\n")
    print(debug.traceback())
    print("----------------------------------------")
end

local function main()
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)

    local cclog = function(...)
        print(string.format(...))
    end
    
    local visibleSize = CCDirector:sharedDirector():getVisibleSize()
    local origin = CCDirector:sharedDirector():getVisibleOrigin()
    
    local function createLayerMap()
        local layerWroldMap = CCLayer:create()

        local bg = CCSprite:create("luaimg/bd.jpg")
        bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
        layerWroldMap:addChild(bg,1)

        return layerWroldMap

    end

    CCDirector:sharedDirector():getRunningScene():addChild(createLayerMap(),3,1)
   
end

xpcall(main, __G__TRACKBACK__)

 

如果你有一些编程经验,学习lua,js这种脚本语言是很轻松的,去网上下载Lua教程可以先了解一下!

(二)在之前我已经写了一个单例方法使用的PublicLuaTodo类,主要就是引用官方给我们提供的CCLuaEngine(Lua支持引擎)

这是一个在cocos2dx中操作Lua的中间件工具类,我已经封装好了,怎么去使用Lua的方法;

下面我直接贴代码:

PublicLuaTodo.h

#include "cocos2d.h"
#include "script_support/CCScriptSupport.h"
#include "../../../lua/cocos2dx_support/CCLuaEngine.h"
#include <string>

using namespace std;
USING_NS_CC;

class PublicLuaTodo:public CCObject
{
public:
    PublicLuaTodo(void);
    ~PublicLuaTodo(void);
    static PublicLuaTodo* getInstance();
    //执行lua文件
    static void toDoLuaFile(string luapath);
    //执行lua语句
    static void toDoLuaString(string luastring);
    //执行一个lua全局的方法
    static void toDoLuaGlobalFunction(string founctionname);
private:
    static PublicLuaTodo* m_instance;
};

PublicLuaTodo.cpp

#include "PublicLuaTodo.h"
CCLuaEngine* pEngine;
PublicLuaTodo* PublicLuaTodo::m_instance = NULL;
PublicLuaTodo* PublicLuaTodo::getInstance()
{
    if(!m_instance)
    {
        
        m_instance = new PublicLuaTodo();
    }
    return m_instance;
}

PublicLuaTodo::PublicLuaTodo()
{
    pEngine = CCLuaEngine::defaultEngine();
    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
    
}

void PublicLuaTodo::toDoLuaFile(string luapath)
{
    std::string path = CCFileUtils::sharedFileUtils()->fullPathForFilename(luapath.c_str());
    pEngine->executeScriptFile(path.c_str());
}

void PublicLuaTodo::toDoLuaString(string luastring)
{
    pEngine->executeString(luastring.c_str());
}

void PublicLuaTodo::toDoLuaGlobalFunction(string founctionname)
{
    pEngine->executeGlobalFunction(founctionname.c_str());
}

PublicLuaTodo::~PublicLuaTodo(void)
{
   if(!pEngine)
   {
       pEngine=NULL;
   }
}

 

Cocos2dx-Lua与C++混合使用_第5张图片

上图是我工程全部准备好的结构;

(三)执行我们已经运写好的Lua文件:

    string luafile = "test/test.lua";
    PublicLuaTodo::getInstance()->toDoLuaFile(luafile);

我把上段代码写到了helloapp里面的关闭方法中, 很方便就能运行起来Lua新加的层!

Cocos2dx-Lua与C++混合使用_第6张图片

5,使用toLua++ 工具类实现在Lua中调用C++方法

(一)在工程中我还引入了一个做适配的类VisbleRect.h是C++写的,主要作用是获取屏幕各个方向上的坐标,

方便使用适配后的坐标点。要使用这个类cocos2dx提供了工具tolua方法,原理就是通这tolua++IPA调用通过

自己创建的XX.pkg文件,生成出对应供lua调用的类LuaCocos2d.cpp接口,lua能对应寻找对应方法在Lua中

使用。

(二)编写需要调用的XX.pkg文件:

定位到:/Users/youmacname/cocos2dx.2.2/cocos2d-x-2.2/tools/tolua++ 中,并在该目录下编写VisbleRect.pkg文件

编写规则参见README翻译如下:  
  1) enum keeps the same
    2) remove CC_DLL for the class defines, pay attention to multi inherites
    3) remove inline keyword for declaration and implementation
    4) remove public protect and private
    5) remove the decalration of class member variable
    6) keep static keyword
    7) remove memeber functions that declared as private or protected 

VisbleRect.pkg

class VisibleRect
{
    static CCRect getVisibleRect();
    static CCPoint left();
    static CCPoint right();
    static CCPoint top();
    static CCPoint bottom();
    static CCPoint center();
    static CCPoint leftTop();
    static CCPoint rightTop();
    static CCPoint leftBottom();
    static CCPoint rightBottom();
};

 


(三)修改/cocos2dx.2.2/cocos2d-x-2.2/tools/tolua++ 中的Cocos2d.pkg,添加$pfile "VisibleRect.pkg"这一行

Cocos2dx-Lua与C++混合使用_第7张图片

(四)继续修改如下路径:

定位到:/cocos2dx.2.2/cocos2d-x-2.2/tools/tolua++/下

Makefile文件

 

Cocos2d.pkg文件

Cocos2dx-Lua与C++混合使用_第8张图片

修改成你自己想生成的路径

(五)打开终端运行./build.sh ,编译生成新的带接口的LuaCocos2d.cpp

(六)将新生成的LuaCocos2d.cpp复制到我们工程目录下

对应工程目录

/Users/youmacname/myluatest/myluatest/libs/lua/cocos2dx_support/

替换掉原有的LuaCocos2d.cpp

(七)这时直接xcodex运行run会报错,需要在工程里面LuaCocos2d.cpp中添加VisbleRect.h头文件的路径。

#include "/Users/youmacname/myluatest/myluatest/Classes/VisibleRect.h"

再点Run就不会报错了,到这一步应该也了解了整个Cococs2dx运行Lua的原理和机制!

恭喜你可以使用VisibleRect里面所提供的静态方法了!意味着Lua也可以调用C++了!!

我们来实际在Lua中操作一下

修改test.lua

Cocos2dx-Lua与C++混合使用_第9张图片

-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(msg) .. "\n")
    print(debug.traceback())
    print("----------------------------------------")
end

local function main()
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)

    local cclog = function(...)
        print(string.format(...))
    end
    
    --local visibleSize = CCDirector:sharedDirector():getVisibleSize()
    --local origin = CCDirector:sharedDirector():getVisibleOrigin()
    
    local function createLayerMap()
        local layerWroldMap = CCLayer:create()

        local bg = CCSprite:create("luaimg/bd.jpg")
        
        --bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
        
        bg:setPosition(VisibleRect:center())

        layerWroldMap:addChild(bg,1)

        return layerWroldMap

    end

    CCDirector:sharedDirector():getRunningScene():addChild(createLayerMap(),3,1)
   
end

xpcall(main, __G__TRACKBACK__)

 

OK,改完之后Run一下

Cocos2dx-Lua与C++混合使用_第10张图片

到现在为止我们已经完成了在xcode上面绑lua并使用tolua++调用C++的方法!

———————————————————————————————————————————————————

Android 上面绑Lua 

如果你没有配置过mac上的android环境,那么请看这篇【cocos2d-x 环境配置-Mac配置篇】

1,同样也是先创建一个新工程;

 ./create_project.py -project XXX-package com.xxx.XXX -language cpp

2,将刚才我们在xcode上写的东西新加的类都移植(复制对应目录就行),并编写对应的.mk文件

Cocos2dx-Lua与C++混合使用_第11张图片

3,工程可能会报错,先导入libPluginPrptocol Cocos2dx提供的扩展包

/Users/youmacname/cocos2dx.2.2/cocos2d-x-2.2/plugin/protocols

右键myluatest 工程->Android->library ->add libPluginPrptocol进来

4,这步是重要环节,也是理解android工程中绑lua是如何工作的!

Cocos2dx-Lua与C++混合使用_第12张图片

按照上图,我们需要对应添加

LOCAL_WHOLE_STATIC_LIBRARIES += cocos_lua_static

lua静态库和我们需要lua单独的.so  android工程

$(call import-module,scripting/lua/proj.android)

OK,现在我们run一下会报错!!和在xcodex上面是一样的原因!我们还得替换掉原有的LuaCocos2d.cpp!

android  $(call import-module,scripting/lua/proj.android) 的真实路径如下:

/Users/youmacname/cocos2dx.2.2/cocos2dx2.2/scripting/lua/cocos2dx_support/

我们需要将LuaCocos2d.cpp替换掉/Users/youmacname/cocos2dx.2.2/cocos2dx2.2/scripting/lua/cocos2dx_support/

下面的LuaCocos2d.cpp

并且和IOS一样还要修改里面的路径,此时路径应该填andriod下面的,可以填绝对路径!

Cocos2dx-Lua与C++混合使用_第13张图片

以上步骤完成就可以点android Run了!!

Cocos2dx-Lua与C++混合使用_第14张图片

成功生成了.so文件,标志着android也运行起来了!

以上就是android  工程中手动绑定并使用tolua++内容!

这篇文章确实有点长,希望对大家有用!Lua下一篇我会说一下如何C++和Lua数据传值,互调方法等我已经处理好的类库;

————————————————————————————————————

本章Xcode源码地址:百度云盘

你可能感兴趣的:(cocos2dx)