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運行起來都行;

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

這個是我用xcode新建出來的Lua項目,里面自帶了一個包Lua文件夾;

也可以使用cocos2dx自帶:

對比后發現用了4個目錄,cocos2dx_support,lua,luajit,tolua

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;
   }
}

 

上圖是我工程全部准備好的結構;

(三)執行我們已經運寫好的Lua文件:

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

我把上段代碼寫到了helloapp里面的關閉方法中, 很方便就能運行起來Lua新加的層!

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.2.2/cocos2d-x-2.2/tools/tolua++/下

Makefile文件

 

Cocos2d.pkg文件

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

(五)打開終端運行./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

-- 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一下

到現在為止我們已經完成了在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文件

3,工程可能會報錯,先導入libPluginPrptocol Cocos2dx提供的擴展包

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

右鍵myluatest 工程->Android->library ->add libPluginPrptocol進來

4,這步是重要環節,也是理解android工程中綁lua是如何工作的!

按照上圖,我們需要對應添加

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下面的,可以填絕對路徑!

以上步驟完成就可以點android Run了!!

成功生成了.so文件,標志着android也運行起來了!

以上就是android  工程中手動綁定並使用tolua++內容!

這篇文章確實有點長,希望對大家有用!Lua下一篇我會說一下如何C++和Lua數據傳值,互調方法等我已經處理好的類庫;

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

本章Xcode源碼地址:百度雲盤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM