[cocos2dx]使用virtual關鍵字

文章撰寫日期︰2013/08/13 12:30
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、前文

今天想要使用virtual關鍵字宣告抽象實作函式,
發現了一些狀況。

二、文章開始

遇到了什麼狀況?

1.cocos2dx官網已經明確的告訴我們不要隨便使用virtual關鍵字。


2.稍微理解一下virtual這個關鍵字在cocos2dx裡的被使用狀態︰

CCNode裡如virtual void onEnter()等抽象實作函式之所以能呼叫到子CCNode的onEnter()是因為CCNode的onEnter()使用了一個宏/巨集︰
void CCNode::onEnter()
{
    //就是這個
    arrayMakeObjectsPerformSelector(m_pChildren, onEnter, CCNode*);

    this->resumeSchedulerAndActions();

    m_bIsRunning = true;

    if (m_eScriptType != kScriptTypeNone)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnEnter);
    }
}

這個宏/巨集被宣告在CCArray.h中︰

#define arrayMakeObjectsPerformSelector(pArray, func, elementType)    \
do {                                                                  \
    if(pArray && pArray->count() > 0)                                 \
    {                                                                 \
        CCObject* child;                                              \
        CCARRAY_FOREACH(pArray, child)                                \
        {                                                             \
            elementType pNode = (elementType) child;                  \
            if(pNode)                                                 \
            {                                                         \
                pNode->func();                                     \
            }                                                         \
        }                                                             \
    }                                                                 \
}                                                                     \
while(false)

當每一個CCLayer向CCScene添增子節點(this->addChild(node))後,
這個宏會將所有收到的子節點
都跑一次onEnter這個被強制規範要實作的函式。
也因此,
我們客製化的CCLayer::onEnter()能夠被呼叫到。

如果要這樣使用,
你的架構需改寫。

3.你宣告岀來的class需要繼承CCObject,
否則會遇到
CCAssert(0, "not implement");

這個錯誤。

三、結論

以上種種原因,
寫了這篇部落格打消使用virtual的念頭。

[cocosBuilder篇]找不到cocosBuilder裡宣告的Tag值

文章撰寫日期︰2013/08/12 19:33
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、問題

遇到了找不到在cocosBuilder裡一個CCLabelTTF宣告的tag值的問題。






二、解決辦法

後來才發現CCBReader無法讀取到CocosBuilder裡CCNode底下的tag值。
如果要抓到tag,必須讓CCLabelTTF脫離CocosBuilder的CCNode架構。


[cocos2dx篇]CCLayerColor沒有顯示

文章撰寫日期︰2013/08/08 17:51
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、問題

今天遇到在cocosBuilder裡使用CCLayerColor,
但在畫面上卻沒有顯示的問題。

二、解決辦法

經爬文後發現cocos2dx\layers_scenes_transitions_nodes\CCLayer.cpp底下
init()有問題。

原本的Code︰
bool CCLayerColor::init()
{
    CCSize s = CCDirector::sharedDirector()->getWinSize();
    return initWithColor(ccc4(0,0,0,0), s.width, s.height);
}
需改成
bool CCLayerColor::init()
{
    CCSize s = CCDirector::sharedDirector()->getWinSize();
    return initWithColor(ccc4(0,0,0,255), s.width, s.height);
}
問題解決。

[Android-JNI篇]Fatal signal 11,找不到JNI函式

文章撰寫日期︰2013/07/17 11:42
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、問題

今天在寫JNI試圖從C++ call JAVA時,
遇到了
Fatal signal 11 (SIGSEGV) xxxx
的問題,
告訴我找不到JAVA層的某個static函式。


二、解決辦法

JAVA端的Code如下
package com.simon.utility;
public class DataManager {
 public static void test(){
  
  Log.i("tag", "into test");
 }
}
 
C++端使用JNI呼叫上面的Java函式
void FileOperator::getAndroidTest(){
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    CCLog("into FileOperator::getAndroidTest(), Involking JNI...");
    
    JniMethodInfo t;
    
    if (JniHelper::getStaticMethodInfo(t, "com/simon/utility/DataManager","test","()V;"))
    {
        CCLog("classID: %d",t.classID);
                CCLog("methodID: %d",t.methodID);
        t.env->CallStaticBooleanMethod(t.classID,t.methodID);
        
    }
#endif
}
 
程式一直跟我報找不到test這個函式,
後來才知道()V;那邊
V後面不用打分號!

題外話︰
()是JAVA端接收參數的值
V是這隻JAVA函式是否有回傳值。

[Android篇]無法使用GET/POST

文章撰寫日期︰2013/07/05 15:37
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、問題

今天使用cocos2dx提供的CCHttpRequest跟伺服器發出GET/POST請求時,
Android端一直無法取得到正確資料,出現以下的LOG︰
response failed
error buffer: Couldn't resolve host 'xxxxxxx.amazonaws.com'

二、解決辦法

這是因為沒有開啟Android端的用戶權限。

註︰
Google對於每一隻APP需要使用到的權限,
都要求開發者必須在AndroidMenifest.xml裡註冊,
這是為了讓Google Play可以在提供使用者下載的地方,
show出這隻APP需要哪些資訊。

如︰這隻APP需要有上網能力、需要讀取您的通訊錄、需要讀取您的外部SD卡等等⋯

Android端的User-Permission需要加入Internet這個Permission。
〈uses-permission android:name="android.permission.INTERNET"/〉

加入後,就能在Android端GET/POST取到資料了。

[cocos2d-x 2.0.x版]開啟一個跨平臺開發的專案

文章撰寫日期︰2013/06/26 14:19
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

此篇僅用於cocos2d-x 2.0.4版

如欲在2.1.x版以上建置專案請參閱此篇。


一、前言


雖然cocos2d-x號稱可以跨平臺開發,
但是實際上在使用時,
仍然是看到他們是各別創立cocos2d-x專案。

這個設計對於跨平臺這件事,
實在是有點「半套」的感覺。

要怎麼樣將Android專案和IOS專案合併起來快速編譯開發?

在這邊分享一點我使用到後期的經驗。

二、文章開始

為了讓Android專案的Resource、Class能和IOS專案一起使用,
並需將cocos2dx-Xcode專案底下的Class和Resource目錄移到最上層Android/Xcode的共用目錄,
這時候原本在Xcode底下的Info.plist專案就會沒地方去了。
把他移到.xcodeproj專案檔相同目錄,
這些資料夾和檔案的關係在我的工作檔中是這樣子的︰


建立專案的方式,
我建議先從Android專案建立起來。
為什麼?
做下去就知道了。

跨平臺開發的第1步︰create Android專案

首先,先到cocos2dx目錄下,
執行create-android-project.sh
假設我們專案名稱命名為Challenge。

執行完後,
順利的話應該會在cocos2dx目錄下,
看到你剛才欲創建的那個目錄。
應該會長成類似底下這個樣子。
我因為很怕日後專案一多,
這樣子創建起來的專案會越來越凌亂,
因此,我將這個專案收納到cocos2dx\workspace底下。
此時路徑變成了cocos2dx\workspace\Challenge。

但也因為這麼做,
我必須要改這個專案(Challenge)底下proj.android\build_native.sh
裡面的設定。(因為我將目錄位置改掉了)
否則你會遇到NDK_MODULE_PATH未定義的這個錯誤。

 

跨平臺開發的第2步︰

建立Xcode專案

在Xcode專案中,
你應該已經將Xcode的cocos2dx template裝好了。
如果尚未安裝者請到cocos2dx底下執行install-templates-xcode.sh
指令是sudo ./install-templates-xcode.sh
安裝好後你應該要在Home/User/你的名字/Library/Developer/Xcode/Templates/cocos2d-x
看到template的檔案,
這樣才能確定你cocos2dx樣版安裝成功。

開啟Xcode,
並建立一個cocos2dx專案
將專案存放在剛才workspace\Challenge底下。

為了讓IOS和Android的Class和Resource共用,
我們將Xcode專案底下的Class和Resource搬到workspace\Challenge底下,
你會看到Android本身就有一些Resource(像icon或什麼的),
將檔案都放在一起吧。

此時xcode應該會岀現遺失了2個目錄的紅色提示,
將他們刪除,
並將新位置的Class和Resource目錄拖進Xcode專案中。

在Finder中,
將Resource\Info.plist檔案拖到IOS專案目錄底下,

並在Xcode重新設定info.plist路徑如下

跨平臺開發的第3步︰

編譯你的Android專案

到你的proj.android目錄底下,
執行./build_native.sh,
這邊已經假設你已經安裝並設定好Android NDK和環境變數。
如果上面的設定都有很務實的做到,
這時候Android專案應該是乖乖的在編譯當中的。
這個編譯動作中有一個很重要的事情就是
你要看到build_native.sh編譯了2個靜態c函式庫︰
libcocos2d.a和libgame.so
這樣才代表Android NDK已經幫你把C語言寫岀來的專案編譯完成。

跨平臺開發的第4步︰

在Eclipse中匯入你編譯好的專案

使用import的方式,
將剛才編譯好的專案開進Eclipse中。

此時應該會看到專案打著紅色xx,
那是因為每一個我們創建立起來的cocos2dx專案,
都要吃cocos2dx-Library。
並且你會看到isLibrary核取方塊是被打V的,
這代表libcocos2dx是一個Library,
本身並不能被單獨啟動。

將剛才打紅色xx我們編譯後的那個專案HelloCCP,
點擊滑鼠右鍵選擇[Properties],

刪掉錯誤的Library引用,
並add剛才設定好的cocos2dx-Library。


三、結論

經過這些編譯和設定,
一個完整同時含有IOS、Android跨平臺開發的cocos2dx專案,
就這麼產生了。

在IOS端,
你只要很單純的在Xcode裡按下run,
即可看到專案的結果。

而在Android端,
每一次都要先使用NDK(build_native.sh)編譯,
才能夠使用編譯後的cocos2dx-Library,
利用OpenGL在Android機器上開啟該畫面。

相關文章

1. 在cocos2d-x 2.1.x / 3.x 版建置全新的專案

[cocosBuilder篇]signal SIGABRT錯誤-狀況2

文章撰寫日期︰2013/05/13 11:35
cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、問題

繼上次sinal SIGABRT錯誤-狀況1的問題後,
今天在使用cocosBuilder上又遇到了另一個signal SIGABRT的錯誤。
但這次是發生在readNodeGraphFromFile發生標籤對照定時的錯誤。

二、解決辦法

經查明後,
發現我在publish ccb腳本後,
又更改了綁定的類別名稱(更改成CategoryUpFloorScene,如下圖所示),
但卻忘了將腳本裡的欲綁定類別更名,
導致腳本發生找不到cocos2d-x類別名稱(CategoryAnimScene,如下圖所示)的錯誤。
改掉就解決問題了。

相關文章

1. [cocosBuilder篇]signal SIGABRT錯誤-狀況1