2013年11月11日 星期一

Eclipse 編譯 Cocos2d-x 的程式碼

http://fecbob.pixnet.net/blog/post/38509887-cocos2d-x%E8%B7%A8android%26ios%E5%B9%B3%E8%87%BA%E9%96%8B%E7%99%BC%E5%85%A5%E9%96%80

1017440  
假如你可以使用和cocos2d相似的api來開發android上面的遊戲,那豈不是更爽?這樣,你就可以毫不費勁地擴大你的遊戲的市場份額(android的使用者數量巨大啊!)

好吧,確實存在這麼一個遊戲框架,她就是cocos2d-x!cocos2d-x採用c++把cocos2d的api重新移植了一遍,,除了一些語法細節上面的差異之外,你可以使用幾乎一樣的api來編寫遊戲。正是由於它是c++寫的,所以可以跨多個平臺,從ios到android、windows、再到linux、bada等!

在這篇教程裡面,你將學習到,如何使用cocos2d-x和c++來編寫一個能夠同時在ios和android設備上面跑的「HelloWorld」程式。

而且,過兩天,我會再出一篇教程,向大家展示一個具體的遊戲例子---一個跨平臺的太空射擊遊戲!

好了,帶上你的iPhone和Android設備,讓我們開始吧!

Hello,Cocos2D-X for iOS!

在繼續之前,確保你先下載最新版本的cocos2d-x。

隨便在你的硬碟的某個位置上面解壓就可以了。注意,這個解壓出來的資料夾的完整路徑名,我們之後會用一個統一的別名$COCOS2DX_HOME來指代。

現在,你已經下載到源碼了,讓我們來安裝專案範本吧!你可以先cd到$COCOS2DX_HOME這個目錄(譯者:指你剛剛解壓縮代碼的存放路徑)下面去。在安裝範本之前,先退出Xcode,然後打開一個終端,並輸入下面的命令:

cd$COCOS2DX_HOME

sudo./install-templates-xcode.sh-u

注意:在上面所示的代碼中,你不能直接輸入$COCOS2DX_HOME,而要輸入實際的路徑。如果你直接輸入了$COCOS2DX_HOME是不會有任何反應的。當然,你可以參考我寫的《如何在macos下面組態集成ios和android遊戲教程》,裡面有講到環境變數的配置。大概方法就是打開~/.bash_profile檔,然後用export來定義環境變數就ok了。

你可能會被要求輸入管理員密碼(加了-u應該是不需要輸入密碼的,不加-u就需要輸入),之後的過程就非常簡單了。在範本安裝好之後,啟動xcode,然後創建一個新的專案。這時,你可以在專案範本對話方塊中看到有cocos2d-x的範本了。不用擔心,cocos2d-x的範本與cocos2d的範本並不會有衝突,因此,你還是可以創建cocos2d的專案。

讓我們來試一下新範本吧!打開Xcode,然後創建一個新的工程,選擇iOS\cocos2d-x\cocos2dx範本,如下圖所示:
1017442 

把工程例句為Cocos2DxFirstIosSample,然後保存。

現在,編譯並運行,你將會看到cocos2d-x的hellowolrd程式跑起來了,如下圖所示:
1017444 

非常簡單,不是嗎?這時,你可以看看xcode裡面的檔,特別是Classes\HelloWorldScene.H和Classes\HelloWorldScene.cpp。如果你也熟悉cocos2d的話,那麼裡面的代碼看起來會覺得非常熟悉---幾乎完全一樣的cocos2dAPI,只是語言是c++而已!

配置cocos2d-x的eclipse開發環境

現在我們已經完成了Xcode4的helloworld程式了,是時候看看如何使用eclipse來配置android的cocos2d-x開發環境了。

這篇教程假設你有一個可以進行Android開發的標準開發環境。如果你還沒有的話,可以參考這篇教程來配置,它裡面提供了詳細的過程,教你如何一步步配置好一個標準的eclipseandroid開發環境。

但是,請等一下。一個標準的eclipseandroid開發環境是專為java開發設計的,而cocos2d-x卻是基於c++來做開發的!

不用擔心,eclipse已經有10年的歷史了,它有許多外掛程式可以支援其它語言的開發,這當然就包括c/C++語言的外掛程式啦。先讓我們來安裝這個外掛程式吧。打開eclipse,然後執行以下步驟:

從EclipseIDE的主工具列上面,選擇Help/InstallNewSoftware。

打開WorkWith核取方塊,並從中選擇一個包含你的eclipse版本名稱的項(如果是最新版的eclipse的話,就選擇indigo)

在外掛程式樹裡面找到ProgrammingLanguages(只有當你複選中「Groupitemsbycategory」時,你才可以看到外掛程式樹。)並打開它.

選擇CDT外掛程式,然後安裝下列元件。(但 是,請注意,你如果直接就點擊C/C++DevelopmentTools的話,你是得不到下圖所示的樣子的,你還需要在 「MobileDevelopment」裡面去查找相關的項)(譯者:我沒找了,直接就選擇了C/C++DevelopmentTools就Next安裝 了)
1017446 

點擊next來完成嚮導,然後等待元件下載並安裝。現在,你可以使用eclipse來開發C/C++專案了!

Set up the Android NDK(Native Development Toolkit)

本來,android開發只能採用java,而且現在市場上面大部分的app也是採用java寫的。

然而,現在你還可以通過NativeDevelopmentToolkit(NDK),使用C/C++來編寫android程式。這種程式設計方式是由Google在2009年6月份引入的,它允許一些元件採用C/C++來編寫,然後通過標準的JAVANativeInterface(JNI)來調用。

安裝NDK的過程非常簡單:

下載最新版本的NDK。here(注意選擇MacOSX平臺).

解壓tar.bz2到任意目錄.之後,我會使用$NDKROOT來指定這個解壓縮後的目錄。

NDK給Android開發帶來了全套的C/C++編譯工具集,可以使用GCC4.4.3來編譯來連結並且可以構建即時安裝的APK包。

有了這套編譯工具集,我們就可以在eclipse裡面集成一些外部的C/C++庫(比如cocos2d-x)。這些庫被編譯成動態庫,然後通過JNI(JAVANativeInterface)與JAVAAndroid體系程式進行交互。

這些編譯工具集可以採用下面兩種方式使用:

獨立模式:直接在你的makefile中使用arm-linux-androideabi-g++.這種方式會增加你的專案的複雜性和可維護性。我推薦你不要使用這種方式。

整合模式:使用$NDKROOT/ndk-buildshell工具,它是一種高度可定制的makefile,專門為NDK庫所設計的。這也是我們這篇教程所採用的方式。
1017448 

解釋JNI和NDK可能會花費大量時間,而且也超出了本教程的討論範圍。現在網路上有許多關於JNI的資源。這裡還推薦一本書,它也討論了JNI這個主題。

如果你需要更多關於NDK的資訊,這裡推薦一本非常好的書,它裡面涵蓋了使用C/C++進行NDK開發,書名是:AndroidNativeDevelopmentKitBeginner’sGuide。這本書覆蓋了NDK程式設計的方方面面,可謂是「從入門到精通」,而且NDK本身也帶有非常詳細的文檔,在$NDKROOT/docs路徑下面。

Hello,Cocos2D-X for Android!

現在,讓我們在Andriod平臺上面來開發一個「Hello,World」程式吧,就像我們之前在ios平臺上的程式一樣。

我們需要通過命令列來完成工作,因為目前還沒有在EclipseIDE裡面集成cocos2d-x的範本。

在$COCOS2DX_HOME目錄下面包含一個shell腳本,叫做create-android-project.sh,我們可能通過它來創建android專案。但是,在運行腳本之前,我們需要在指令檔的頂部做一些修改:

#setenvironmentparamters

NDK_ROOT_LOCAL="/home/laschweinski/android/android-ndk-r5"

ANDROID_SDK_ROOT_LOCAL="/home/laschweinski/android/android-sdk-linux_86"

修改上面這些行,把NDK_ROOT_LOCAL指向你安裝AndroidNDK($NDKROOT)的位置,同時把ANDROID_SDK_ROOT_LOCAL指向你安裝AndroidSDK位置。(譯者:這裡其實可以不用修改,讀者可以打開這個sh腳本去看看為什麼。如果之前看過我的配置教程,裡面有配置一個全域的NDK_ROOT和ANDROID_SDK_ROOT。這個腳本在判斷有全域的環境變數存在的時候,會直接替代NDK_ROOT_LOCAL和ANDROID_SDK_ROOT_LOCAL。)

現在,可以運行create-android-project.sh腳本了,然後你會接收到一系列的提示輸入。我們將一個個向您解釋一下:

第一個提示要求你「Inputpackagepath」。這個包名會給後面的java代碼使用。你可以使用你的功能變數名稱反過來寫,類似寫ios的bundleID。比如com.yourdomain.samplecocos2dxandroid,記住實際輸入的時候要替換掉「com.yourdomain」。

接下來,你會得到一系列可用的AndroidAPI和它們的id號。這個具體取決於你的機器上面安裝的AndriodAPI的情況。

最後,你需要提供專案的名稱,在這裡取名為samplecocos2dxandroid:

命令列的輸出大致如下:

bash-$./create-android-project.sh

Inputpackagepath.Forexample:org.cocos2dx.example

org.jymc.samplecocos2dxandroid

...

AvailableAndroidtargets:

----------

...

----------

id:9or"GoogleInc.:GoogleAPIs:15"

Name:GoogleAPIs

Type:Add-On

Vendor:GoogleInc.

Revision:1

Description:Android+GoogleAPIs

BasedonAndroid4.0.3(APIlevel15)

...

inputtargetid:

9

inputyourprojectname:

samplecocos2dxandroid

Createdprojectdirectory:/Users/jymen/development/cocos2dx/samplecocos2dxandroid

...

Addedfile/Users/jymen/development/cocos2dx/samplecocos2dxandroid/AndroidManifest.xml

Addedfile/Users/jymen/development/cocos2dx/samplecocos2dxandroid/build.xml

Addedfile/Users/jymen/development/cocos2dx/samplecocos2dxandroid/proguard.cfg

bash-$

注意「Createdprojectdirectory:」這一行是指令檔最後輸出來的,這個輸出的路徑也就是你的Andriod專案被創建好的路徑。我這裡指的是/Users/jymen/development/cocos2dx/samplecocos2dxandroid,如上圖所示:

Note:Donottrytomovetheprojectfromthatlocationtoadifferentlocation.Atleastoneofthescriptswe’llworkwithinthenextsectionwillnotworkifyoudo.

構建工程

這裡有兩個步驟來構建專案----首先通過命令列腳本編譯c++代碼,然後通過ecipse來編譯java代碼。

為了編譯c++代碼,我們需要切換到$PROJECT_HOME/android資料夾下面去,然後在終端裡面輸入下列命令:

./build_native.sh

你應該會看到下面類似的輸出:

Gdbserver:[arm-linux-androideabi-4.4.3]libs/armeabi/gdbserver

Gdbsetup:libs/armeabi/gdb.setup

Compile++thumb:cocos2d<=CCConfiguration.cpp

Compile++thumb:cocos2d<=CCDrawingPrimitives.cpp

:

:

:

Compile++thumb:cocos2d<=CCTileMapAtlas.cpp

Compile++thumb:cocos2d<=CCTouchDispatcher.cpp

Compile++thumb:cocos2d<=CCTouchHandler.cpp

Prebuilt:libstlport_static.a<=/sources/cxx-stl/stlport/libs/armeabi/

SharedLibrary:libcocos2d.so

Install:libcocos2d.so=>libs/armeabi/libcocos2d.so

Compile++thumb:cocosdenshion<=SimpleAudioEngine.cpp

Compile++thumb:cocosdenshion<=SimpleAudioEngineJni.cpp

SharedLibrary:libcocosdenshion.so

Install:libcocosdenshion.so=>libs/armeabi/libcocosdenshion.so

Compile++thumb:game_logic<=AppDelegate.cpp

Compile++thumb:game_logic<=HelloWorldScene.cpp

SharedLibrary:libgame_logic.so

Install:libgame_logic.so=>libs/armeabi/libgame_logic.so

Compile++thumb:game<=main.cpp

SharedLibrary:libgame.so

Install:libgame.so=>libs/armeabi/libgame.so

這裡就是在編譯cocos2d-x庫和你的專案裡面的c++檔。

為了編譯java代碼,我們需要創建一個eclipse工程---這可比命令列要方便多了。:)

打開Eclipse,然後他吃軟飯File\New \Other,選擇Android\AndroidProject,然後點擊Next,在ProjectName裡面輸入 samplecocos2dxandroid,然後選擇Createprojectfromexistingsource,然後流覽 到$PROJECT_HOME/android資料夾,如下圖所示:
10174410 

點擊Next,選擇一個Androidversiontotarget(這裡選擇的是3.2,你可以選擇任何一個)
10174412 

點擊Finish,好了,現在你有一個工程了!
10174414 

在左邊的樹上右擊專案,選擇RunAs\AndroidApplication,然後AVD(AndroidVirtualDevice)就會啟動,然後就會跑出來Hello,Cocos2D-X專案了!
10174416 

注意:如果程式沒有啟動的話,你需要按照提示去創建一個AVD來測試。更多的細節,請參考GettingStartedwithAndroidDevelopment這篇教程。

恭喜你,你現在有一個「Hello,World」專案可以同時跑在ios和android上面了!

在Eclipse裡面定義一個結合java/c++的工程

通過命令腳本來編譯c++代碼,完了之後用eclipse來編譯java代碼,這種來回切換的做法非常笨重。如果全部可以用eclipse來完成的話,那麼生活會更簡單一些。

幸運的是,我們可以告訴eclipse,我們的android專案是一個集成java/c++的跨語言專案!

為此,我們在左邊的專案樹上選擇samplecocos2dxandroid,然後從功能表裡面選擇File\New\Other,然後從對話方塊裡面選擇C/C++\ConverttoaC/C++Project,如下所示:
10174418 

點擊Next。在下一個螢幕裡面,選中你的專案,然後選擇c++選項按鈕,然後為Projecttype指定Makefileproject\OtherToolchain,如下所示:

10174420 
點擊完成。這時eclipse會詢問你是否打開C/C++視圖,當對話方塊出現的時候,選擇NO。

接下來的步驟就是修改專案設置,指定如何運行我們的make命令。在左邊的專案樹上,右擊samplecocos2dxandroid工程,選擇Properties,然後選擇C/C++build

10174422 
取消「Usedefaultbuildcommand」核取方塊,然後在build文字方塊中輸入下面的命令:

bash${workspace_loc:/samplecocos2dxandroid}/build_native.shNDK_DEBUG=1V=1

點擊Apply,然後點OK。

回到ecipse,從主功能表中選擇Project\BuildAll,這時你可以在ecipse的主控台輸出中看到c++make在運行。
10174424 

我們仍然有一些警告需要解決。想知道我是什麼意思嗎,你打開jni/helloworld/main.cpp,這裡你會看到一系列的警告,如下所示:
10174426 

這些警告之所以會出現,是因為我們沒有配置正確的c++包含路徑。為了解決它,我們右擊samplecocos2dxandroid工程,然後選擇Properties\C/C++General\PathandSymbols\GNUC++。

選擇Add...按鈕來選擇下面的目錄,之後點擊Apply和OK。

$(NDKROOT)/platforms/android-9/arch-arm/usr/include

$(COCOS2DX_HOME)/cocos2dx/include

注意:不用忘了使用實際的路徑來替換掉$(NDKROOT)和$(COCOS2DX_HOME)。
10174428 

點擊Apply,這時會提示你是否重建索引。直接點擊yes繼續就可以了。

現在,你再看看main.cpp,你會看到大部分警告已經消失了。
10174430 

但是,AppDelegate.h檔還是找不到。這是因為AppDelegate.h是在$PROJECT_HOME\Classes資料夾下面。這個資料夾對我們來說非常重要,因為它包含了我們工程裡面的可移植的c++類,比如HelloWorldScene.cpp等。

當我們創建eclipse專案的時候,我們必須選擇$PROJECT_HOME\android資料夾,因為eclipse需要一個AndroidManifest.xml檔。但是,這樣的話,我們的工程就不包括關鍵的「Classes」資料夾了,這也是為什麼我們會得到這麼多警告的原因。

讓我們來修正它吧。右擊samplecocos2dxandroid專案,選擇Properties\C/C++General\PathsandSymbols\Sourcelocation。點擊LinkFolder,然後複選中Linktoafolderinthefilesystem,接著流覽到$PROJECT_HOME資料夾,並指向Classes目錄,最後點Apply和OK。

10174432 
你現在可以在檔樹裡面看到Classes目錄了,而且在main.cpp裡面的#include「AppDelegate.h」警告也應該消失了。

Eclipse工程裡面還會有許多警告,但是,這是因為eclipse對於解析c++標頭檔的能力並不強大。為了消除這些警告,我們又需要設置一下專案設置。(右鍵點工程,然後選擇Properties),把CodeAnalysis部分的warnings關閉,如下圖所示:
10174434 

然後點擊Apply和OK,這時,你就得到一個工程可以在eclipse裡面進行編輯了。

What About the JAVA Code?

這時你在eclipse裡面再找找看,你會在src和gen目錄下面找到一些java代碼,你肯定很好奇這些代碼是幹嗎用的。

Andriod開發採用的主要語言是java,這個專案範本已經為我們創建了一些java框架代碼,用來載入c++編寫好的動態庫。

一般情況下,你是不需要修改這些java代碼的,但是,還是讓我們來看看src\com\xxx\samplecosos2dxandroid\samplecocos2dandroid.java這個類。

這個類包含了主AndroidActivity類,當應用程式啟動的時候會載入。它首先通過NDK來請求編譯好的c++動態庫。(如果採用的是最新版的coocs2dx的話,下面只會載入一個game庫)

10174436 
由於類是從Cocos2dxActivity所派生,在後臺cocos2d-x會把控制權移交給c++的AppDelegate的initInstance方法來處理,最後applicationDidFinishLAunching方法也就被執行起來了。

因此,再重申一遍,java代碼只是一些包裝代碼,大部分情況下我們都不要去修改它,因為我們的遊戲邏輯是由c++寫的。

Sotorepeat,theJAVAcodejustcontainswrappercodethatyouwillrarelyneedtochange,sinceallthegame’slogicwillbeinsidetheC++code.

連接andriod和ios專案結構

現在,我們有兩個cocos2d-x的專案了,一個是ios下面的,一個是andriod下面的。我們的目標是讓兩個工程共用同樣的目錄,這樣就可以使用同樣的c++檔了。

我們兩個專案裡面,都有一個資料夾叫做「Classes」,它包含了我們的可移植的遊戲代碼(如下圖:android的在左邊,ios的在右邊)
10174438  
如果你仔細看看eclipse和xcode裡面的Classes目錄,你會發現這些c++檔完全相等。因此,我們需要做的就是讓兩個專案指向同一個資料夾就ok了!

為了實現這個目標,在xcode裡面打開Cocos2DxFirstIosSample專案。選擇Classes分組,然後點擊Delete,選擇「MovetoTrash」;

接下來,右鍵ProjectNavigator,選擇「NewGroup」,然後重命名為Classes。點鍵Classes,點擊AddFiles。然後選擇$PROJECT_HOME\Classes目錄,同時確保「Copyitemsintodestinationgroup’sfolder」沒有被選中!
10174440 

然後clean並rebuildxcode專案,並運行一下,確保一切ok。

恭喜,現在基礎配置全部弄好了!你可以試著在eclipse裡面修改,xcode這邊運行,或者xcode裡面修改,eclipse裡面運行了。

什麼時候使用Xcode,什麼時候使用Eclipse?

現在,你有兩個專案了,那麼問題馬上就出來了,我們到底什麼時候該使用哪一個呢?

使用cocos2d-x通常的開發策略是,首先在ios上面通過xcode來測試,確認沒問題後,再通過eclipse來測試。只需要在心裡記住下面幾點就行:

經常測試.開發完一個小功能之後,就應該在andriod上面測試看行不行。這樣的話,就不至於遇到問題找不到了。

在多個設備上面測試:現在市場上面有大量的android設備,而且它們的差別很細微,所以,你要盡可能多地測試多種不同型號的設備。

當然,你也可以先在andriod上面測試,然後再在ios上面測試。但是這樣肯定會降低你的生產率。因為xcode比eclipse反應速度更快,而ios模擬器比android的模擬器的啟動速度也要快一些。

調試技巧

在ios上面調試cocos2d-x和cocos2d的方法差不多,這裡也沒什麼多講的。

然而,對於Android,這裡有幾點需要注意下。

當使用NDK來調試的時候,一個「服務端的」gdb和gdbcoNtext被ndk-buildshell腳本塞到APk裡面去了。這個遠端的gdb調試器可以與任何gdb相容的用戶端進行通信。

Eclipse裡面最好的gdbagent就是NVidiadebugmanagerplugin,但是安裝這個外掛程式不在本教程的討論範圍之內。

注意:如果你想安裝NVidiaDebugManagerplugin,你首先到這個頁面下載完整的TegraAndroid開發包,即便你可能現在並不需要它。然後,安裝TegraDeveloper,它會提示你安裝哪些項,然後你可以選擇NVidiaDebugManagerplugin這個外掛程式了。當你安裝完之後,它並沒有包外掛程式安裝到eclipse裡面去,而是把zip檔放在你的硬碟的某個位置,你可以參考這個pdf文檔來進行安裝。

我發現在一些物理設備(比如SamsumgGalaxyS),remotedebugger老是啟動不了,但是使用AVD就可以正常啟動。

為了啟動一個debug會話,你可以選擇你的專案,然後右擊DebugAsAndroidNDKapplication,如下圖所示:

10174442 
請注意,只有你安裝了NVidiadebugmanagerplugin,你才會在右擊的時候看到AndroidNDKApplication這個選項。

你可以在一行代碼上面按兩下來設置一個中斷點,如下所示:
10174444 

當中斷點到達的時候,它將會停留在中斷點所在行:
10174446 

悲催的是,使用gdb來調試android有時候並不管用,所以,你可能需要添加一些額外的tracing系統。想知道更多的資訊,請聯繫我,我將與大家分享這些tips。

何去何從?

恭喜你,你現在可以使用cocos2d-x來開發iphone和android下面的遊戲了。

請耐心等待我的第二篇教程吧,它將帶你一起開發一個跨平臺的太空射擊遊戲,當然是使用cocos2d-x啦!

原文連結位址:HTTP://www.raywenderlich.com/11283/cocos2d-x-for-ios-and-android-getting-started