Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 從Cocos2d-x2遷移到Cocos2d-x3的過程分享

從Cocos2d-x2遷移到Cocos2d-x3的過程分享

編輯:關於Android編程

核心代碼遷移相對順利,大致流程如下:

一、創建項目

    1) cd cocos2d-x-3.0rc0;
    2) 執行setup.py,設置引擎依賴的環境變量,腳本會將COCOS_CONSOLE_ROOT和ANT_ROOT寫入到~/.bash_profile中; 執行source ~/.bash_profile使得環境變量生效;
    3) 在cocos2d-x-3.0rc0下建立projects目錄;
    4) 利用cocos2d-console工具建立新項目: cocos new GameDemo -p com.tonybai.game.gamedemo -l cpp -d ./projects
    5) cd ./projects/GameDemo,我們可以看到項目目錄結構如下:
     復制代碼 代碼如下:bin/  Classes/  CMakeLists.txt  cocos2d/  proj.android/
      proj.ios_mac/  proj.linux/  proj.win32/  Resources/
    6) 執行cocos compile -p android -j 4  –ap 19 -m release,這個Demo的apk就會被生成,大致就是一個cpp-empty-test;

二、 代碼移植
   
     代碼移植的主要工作包括:
    1) 改名
            帶有CC前綴的類名大都要將前綴去掉;
            各主要類的單例方法sharedXXXX都改為getInstance;

    2) 菜單、按鈕事件處理      
            由menu_selector(GameScene::menuStartCallback) 改為CC_CALLBACK_1(GameScene::menuStartCallback, this);

    3) 觸屏事件處理

            在Cocos2d-x 2.2.2中,我們直接使用Layer的setTouchEnabled(true),並Override 三個觸屏事件處理函數;
            在新版引擎中,我們需要建立事件Listener,並將Listener注冊到全局EventDispatcher中,諸如:

復制代碼 代碼如下:
auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(true);
        listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
        listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
        listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

然後將這裡的三個事件處理方法實現出來即可。

核心功能遷移後,GameDemo在genymotion 4.4 Android模擬器以及真機上都能正常運行,在模擬器上能保持40左右的幀率,在真機上幀率一直在60左右。玩了一會後,感覺引擎渲染性能的確有提升, 而且這種提升是可以在真機上直觀感受到的。

不過好景不長,我又嘗試將GameDemo在genymotion 2.3.7 Android上運行,這回得到的結果卻是:黑屏。 又將Cocos2d-x 3.0rc0自帶的cpp-empty-test編譯後放到模擬器上運行,得到了同樣的黑屏結果,顯然這可能是rc0的一個問題。在Cocos2d-x forum上粗略搜到的結果是:升級到最新版本可以解決黑屏問題。於是到官方下載目前最新發布版Cocos2d-x 3.0rc2。這裡也吐槽一下:cocos2d-x引擎包Size太大了,似乎也沒有提供什麼patch文件,導致每發一個版本都要下載幾百M的包。官方 git repository也太大了,嘗試clone了幾次都失敗了,最終還只能下載源碼的zip包。

Cocos2d-x 3.0rc2下載解壓後,先編譯了一下cpp-empty-test,然後部署到Android 2.3.7上運行,這回“黑屏”的確不見了,看來rc2修正了這個問題。接下來就是將我的GameDemo移植到rc2上了。

我用解壓後的“cocos2d-x 3.0rc2”替換GameDemo下的cocos2d,然後運行cocos compile編譯,install到模擬器行運行,程序啟動失敗,從monitor logcat中看到一行錯誤日志:

 “ANativeActivity_onCreate not found”

怎麼會呢?ANativeActivity_onCreate是由NDK的 native_app_glue static library提供的,怎麼會找不到呢?

於是乎打開GameDemo/cocos2d/cocos/2d/platform/android/Android.mk打算查看一下究竟:
復制代碼 代碼如下:
LOCAL_WHOLE_STATIC_LIBRARIES    := cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static

include $(BUILD_STATIC_LIBRARY)

$(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)

Android.mk內容中居然沒有將native_app_glue列入,又翻看了一下cocos2d-x 3.0rc0中的同位置Android.mk,後者是有native_app_glue的庫依賴的。難道是rc2這塊忘記了?於是我嘗試將 native_app_glue依賴加上:
復制代碼 代碼如下:
LOCAL_WHOLE_STATIC_LIBRARIES   := android_native_app_glue cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static

include $(BUILD_STATIC_LIBRARY)

$(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)
$(call import-module,android/native_app_glue)

再次嘗試編譯,不過這次連編譯都沒能通過,錯誤的build結果如下:
復制代碼 代碼如下:
/home1/tonybai/android-dev/adt-bundle-linux-x86_64/android-ndk-r9c/sources/android/native_app_glue/android_native_app_glue.c:232: error: undefined reference to 'android_main'
collect2: error: ld returned 1 exit status
make: *** [obj/local/armeabi/libgamedemo.so] Error 1

從結果來看,鏈接器沒能找到native_app_glue中android_main對 應的函數體定義。android_main可是cocos2d-x 3.0引擎提供的實現啊。於是乎再次進入到rc2引擎代碼中查找原因,結果卻讓我很是吃驚:“NativeActivity被引擎移除了”!cocos2d/cocos/2d/platform /android目錄下面已經沒有了nativeactivity.h和nativeactivity.cpp了:

復制代碼 代碼如下:
$ ls -F cocos2d/cocos/2d/platform/android
Android.mk         CCApplication.h  CCDevice.cpp            CCFileUtilsAndroid.h  CCGLView.cpp  CCPlatformDefine.h  java/             jni/
CCApplication.cpp  CCCommon.cpp     CCFileUtilsAndroid.cpp  CCGL.h                CCGLView.h    CCStdC.h            javaactivity.cpp

我們看到了一個新文件:javaactivity.cpp,打開該文件,我們發現了和cocos2d-x 2.2.2版本類似的名字:Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit。難道rc2針對 Android平台的引擎入口代碼回退到2.x版本的設計了?於是乎趕緊進到/cocos2d/cocos/2d/platform/android/java/src/org/cocos2dx/lib目 錄下一看究竟。

果不其然,一切看起來都那麼的熟悉:Cocos2dxActivity.java、Cocos2dxGLSurfaceView.java、 Cocos2dxRenderer.java….。自此可以斷定,rc2中Android平台的引擎設計退回到了2.x版:
    – 你的GameActivity要集成Cocos2dxActivity;
    – mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer())時,GLThread(渲染線程)誕生
    – 死循環調用Cocos2dxRenderer.onDrawFrame
    – 引擎邏輯就在Cocos2dxRenderer.onDrawFrame中被執行。

回到了2.2.2版本設計的引擎在性能上是否會像rc0那樣給人以直觀提升的感覺呢,即便渲染器是新寫的?真機測試的結果表明,沒有直觀感覺到提 升。難道是Native Thread(pthread_create創建)和Java Thread之間的差別?不得而知,後續慢慢體會吧。

另外要提一句:javaactivity.cpp將以往2.2.2版本放在項目jni中的 Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit挪到了引擎中,本來就是基本不變的代碼, 放在引擎中的確更好。rc2的設計回歸也有一定好處,一是以前對引擎的認識還適用,二呢就是適合集成在2.2.2版本中的第三方工具的方法應該同樣適合3.0rc2版本,這樣移 植成本估計會小些。這樣我們針對新的3.0引擎,重點還是去關注渲染器、事件分發機制以及物理引擎的變化吧。

事實上NativeActivity是在rc1就被移除了,這種較大的改動讓人始料不急。這麼大的改動,這麼短時間發布,讓人對目前的 3.0引擎,至少是Android版本引擎的質量表示些許擔憂啊。不知道3.0正式版中這塊的代碼會變啥樣,拭目以待吧。

BTW,rc2版本cpp-empty-test在Android 2.3.7模擬器上的幀數在10幀以下,我的Demo也只有5幀,而在4.4版本模擬器上,可以達到40幀,還好還好。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved