[cocos2d-CocosBuilder篇]compile(編譯製作)自己專用的CocosBuilder

文章撰寫日期︰2013/08/30 23:20
cocos2dx使用版本︰v 3.0 alpha 0
cocosBuilder使用版本︰v 3.0 alpha 5

一、前言

CocosBuilder使用上很方便,
但想要改一些程式碼,
或者模版編譯岀來的東西離自己的需求離很遠,
該怎麼辦?

答案是複製原始碼修改自己想要的

筆者在學會怎麼載入並製作自己想要的cocosBuilder遇到了很大很大很大的阻礙(stuck in it),
現在會了,
不吝嗇的在部落格上跟大家分享。

廢話不多說,
我們看下去。

二、文章開始

步驟1 從gitHub上複製一份原始碼到你的桌機上

我們需要在github上clone一份cocosBuilder的原始碼至桌機裡,
底下放上一張示意。

步驟2 將submodule也複製下來

很多人都漏作或卡在這個步驟,
其實這個步驟在cocosBuilder下載下來後,
README.md檔裡寫得相當清楚︰

Cocos2d and other extensions are provided as a submodules to this project. To be able to compile the source code you need first check out the module. Change directory into the top (this) directory of CocosBuilder and run:
cocos2d和其它的擴充套件都使用了submodule(在git裡維護一個專案底下的次專案我們用submodule,這個次專案是一個被共用的Library,像我們開發Cocos2d-x遊戲都要用到最基本的Library:cocos2d一樣),如果你希望能夠編譯您的code,你就一定要下載這個module(這裡指Cocos2d Library)。請在您的terminal視窗,下載完cocosBuilder源碼(下列第1行)後,進入cocosBuilder目錄再打上下列第3行指令,便可以下載cocosBuilder需要的submodule。

    $git clone https://github.com/cocos2d/CocosBuilder //下載CocosBuilder源碼
    $cd CocosBuilder
    $git submodule update --init --recursive //下載CocosBuilder源碼需要的Library

包含我,
都是不看說明文件的那一個(><)。

步驟3 Xcode的輸岀Target設為cocosBuilder

一樣,說明文件中接著寫道︰

When building CocosBuilder, make sure that "CocosBuilder" is the selected target (it may be some of the plug-in targets by default).
當在建置cocosBuilder專案時,請確定"CocosBuilder"是您選擇的建置target(因為有時候還會有很多其它的plug-in在target列表中),沒有選擇這個動作可能會導致您的專案怎樣都無法run起來


三、總結

經過2次的git下載(第1次下載cocosBuilder源碼,第2次下載它需要的submodule)並選擇target為cocosBuilder後,
整個專案就被編譯起來了。
編譯出來的.app檔案會放在product資料夾底下。
把它複製到你容易使用的地方吧(像是應用程式資料夾底下)!

[cocos2dx-JSB篇]使用CCControlButton擴充元件

文章撰寫日期︰2013/08/30 23:20
cocos2dx使用版本︰v 3.0 alpha 0
cocosBuilder使用版本︰v 3.0 alpha 5

一、前言

CCControlButton擴充件在cocos2dx2.1.4版尚未得到完整的JSB Binding支援,
如同前一篇所言,
因此只好忍痛改用cocos2dx-3.0alpha0版。

但是,
卻發現cocosBuilder編譯岀來的HTML5編碼仍然說不支援CCControlButton,
岀現 Cannot call method 'setCallback' of undefined.的錯誤。

筆者記︰
不僅是CCControlButton無法使用(cocos2dx-html5端沒有寫接收CCControlButton的Callback),連一些基本.width或.height的指令都會無法用。

二、文章開始

百思不得其解,
仔細查看coocsBuilder編譯岀來的boot-html5.js檔才發現這當中大有文章。

以下是boot-html5.js檔編譯岀來的原內文︰

(function () {
    var d = document;
    var c = {
        COCOS2D_DEBUG:2, //0 to turn debug off, 1 for basic debug, and 2 for full debug
        box2d:false,
        chipmunk:true,
        showFPS:true,
        loadExtension:true,
        frameRate:60,
        tag:'gameCanvas', //the dom element to run cocos2d on
        //engineDir:'../../../../cocos2d/',
        SingleEngineFile:'cocos2d-html5.min.js',
        appFiles:[
          'js/ApiBank.js',
    'js/ChoiceScene2.js',
    'js/CommonUtil.js',
    'js/DoorScene.js',
    'js/HomeScene.js',
    'js/PlayScene.js',
    'js/Questions.js',
    'js/StartScene.js',
    'js/TemplateScene.js',

            'resources-html5.js',
            'boot2-html5.js'
            ]

};
    window.addEventListener('DOMContentLoaded', function () {
        //first load engine file if specified
        var s = d.createElement('script');
        /*********Delete this section if you have packed all files into one*******/
        if (c.SingleEngineFile && !c.engineDir) {
            s.src = c.SingleEngineFile;
        }
        else if (c.engineDir && !c.SingleEngineFile) {
            s.src = c.engineDir + 'platform/jsloader.js';
        }
        else {
            alert('You must specify either the single engine file OR the engine directory in "cocos2d.js"');
        }
        /*********Delete this section if you have packed all files into one*******/

            //s.src = 'Packed_Release_File.js'; //IMPORTANT: Un-comment this line if you have packed all files into one

        d.body.appendChild(s);
        document.ccConfig = c;
        s.id = 'cocos2d-html5';
        //else if single file specified, load singlefile
    });
})();

從這段code可看見,
cocosBuilder怎麼讓JSB Binding岀來的code如何透過cocos2d-html5在HTML5繪圖,
原來是用了以下這個微型化引擎︰

SingleEngineFile:'cocos2d-html5.min.js',

cocosBuilder在編譯成HTML5檔時,
自動寫入了這個很簡易的cocos2d-html接口,
讓我們攢寫的JSB-Binding Code可以和HTML5溝通,
也因為是微型化的版本,
我們需要改用被註解掉的
engineDir:'../../../../cocos2d/',
來獲得完成的cocos2d-html5接口支援。

在gitHub上將完整的coocs2d-html複製下來,
將其下cocos2d資料夾對應到上面
engineDir:'../../../../cocos2d/',
的路徑,
即可獲得完整的cocos2d-html支援,
此時,
CCcontrolButton也將能獲得完全的html5版支援!

三、結論

cocos2d家族需要很大的effort才能搞懂許多事, 有時候不妨耐心去研究, 當搞懂一些事情時, 是很美妙的一件事的。

相關文章︰

compile自己專屬的cocosBuilder!

[cocos2dx-JSB篇]callbackNode.setCallback is not a function錯誤

文章撰寫日期︰2013/08/28 11:48
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題

今天在Cocos2d-x2.1.4使用JSB,
cocosBuilder上使用CCControlButton這個Extension元件時,
回報我callbackNode.setCallback is not a function的錯誤。

二、解決辦法

cocos2dx2.1.4版還沒有針對CCControlButton做JSB Binding的支援,
如果要使用的同鞋,
建議直接放棄2.1.4版
不然就是不要使用CCControlButton這個元件...

因為我曾試過要修改2.1.4版做CCControlButton的Binding,
但改版工程實在太皓大...

下列是改版工程動到的Code...
CCControlButton異動部份

=====JSB Biding端====
scripting/javascript/bindings/jsb_cocos2dx_extension_manual.cpp
scripting/javascript/bindings/js_bindings_config.h
scripting/javascript/bindings/js/jsb_cocos2d_extension.js
scripting/javascript/bindings/ScriptingCore.h
scripting/javascript/bindings/ScriptingCore.cpp
scripting/javascript/bindings/js/jsb_cocosbuilder.js
scripting/javascript/bindings/cocos2d_specifics.cpp

extensions/GUI/CCControlExtension/CCControl.cpp


=====觸控事件=====
extensions/CCBReader/CCBAnimationManager.h

extensions/CCBReader/CCBAnimationManager.cpp
extensions/CCBReader/CCBReader.cpp
extensions/CCBReader/CCBReader.h
extensions/CCBReader/CCNodeLoader.cpp

如果仍要改的同鞋,
我提供github上的參考連結︰
1. 官網討論串
2. dumganhar(James Chen)針對cocos2dx3.0版的Binding修改記錄

三、總結

cocos2d-x2.1.4版在C++端趨於成熟,
而在JSB端像個初生兒...

[cocos2dx-JSB篇]TypeError: _ccbGlobalContext[documentControllerName] is not a constructor錯誤

文章撰寫日期︰2013/08/24 18:25
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題
今天在使用jsb開發時, 遇到
TypeError: _ccbGlobalContext[documentControllerName] is not a constructor
的錯誤。

二、解決辦法

有幾種原因,
但主要原因都是你目前欲使用的Scene實例化失敗。

1.沒有將新的js檔宣告進main.js

在main.js檔中宣告require("新的Scene");

2.cocosBuilder端JSController綁定的js檔裡面沒有編譯通過

可能是忘了宣告這個Scene的實體物件,
或這份js文件裡面使用的語法有誤,
導致JSB在載入該js檔時宣告失敗。

[JSB-Android篇]XmlHttpRequest元件在Android端使用回傳reponse failed

無法查看此摘要。請 按這裡查看文章。

[JSB-IOS篇]遇到 error: failed to attach to process ID 0 resources

文章撰寫日期︰2013/08/24 04:20
文章修改時間︰2013/08/31 23:36
文章修改次數︰2
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題

今天遇到Xcode回報
error: failed to attach to process ID 0 resources

導致cocos2dx專案在Xcode上一直無法啟動的問題。

二、解決辦法

我遇到的問題是Resources資料夾同時做為Group,
又同時做為References產生的問題。

在Stackoverflow有網有提到︰
I experienced the same problem, and after a while I found out that it was due to the fact that my XCode project included a Folder Reference to a folder named Resources.
It seems that XCode doesn't like that name.
Just removing the folder reference or renaming the folder solved the issue.
將藍色資料夾的Resources(References)移除即可解決問題。

如果這個問題解決不了你的狀況,
請再爬文,
因為看起來造成這個error的原因有很多。

2013/08/31
今天又遇到一次問題,
解決辦法是到
/Users/你的名稱/Library/Developer/Xcode/DerivedData
底下去把專案刪掉,IOS Simulator重新reset,
最後才告訴我在main.js裡多宣告了一個已被我刪除的require導致整隻程式run不起來。

[JSB-Androdi篇]遇到Errors running builder 'Integrated External Tool Builder' on project 'xxx'

文章撰寫日期︰2013/08/24 04:04
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題

在專案初始化啟動後, Eclipse岀現下列狀況︰

Errors running builder 'Integrated External Tool Builder' on project 'xxx'.


二、解決辦法


將底下的這個工具(Invalid External Tool Builder)移除即可

未確定錯誤

error: failed to attach to process ID 0
(可能是JSB Binding專案有漏掉,重拉進來看看,不要用Reference,用Group)

找不到js檔案資源
可能是main.js裡require("xxxx.js")忘記打上根目錄
譬如 require("javascript/xxxx.js")

[cocos2dx-JSB篇]JSB教學-跨岀cocos2dx-Javascript的第一步!!(此篇為轉載文)

文章撰寫日期︰2013/08/24 01:54
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5
文章來源︰劉松的Github教學

前言

由國人自己研發的開源遊戲引擎Cocos2d-x,在很短的時間內就風靡全球,來自多個國家的開發者均參與貢獻代碼,其優秀毋庸置疑。但是,年輕的 Cocos2d-x正處於快速發展階段,圍繞其周邊的配套工具、文檔、教程等等均尚不完善。我本人在學習的過程中就體會過把Google、 StackOverflow、github以及官方論壇等等翻個底朝天都找不到相關資料的窘境。這也是本篇教程誕生的根本原因。

因我本人亦是剛剛加入Cocos2d陣營學習不久,加上自身能力有限,教程之中若有錯誤,還望不吝指出,我將及時更新修復錯誤。另外,本人熱愛開源,因此本教程亦設定為“開源教程”。希望能藉此拋磚引玉,讓更多的朋友參與到這個教程的編寫過程中來,共同學習和完善相關內容,讓更多人後來者受益。

一、Cocos2d-x JavaScript Binding簡單介紹

眾所周知,Cocos2d-x的主要開發語言是C++,而Cocos2d-x JavaScript Binding則是基於Cocos2d-x用JavaScript語法來編寫遊戲。 Cocos2d-x JavaScript Binding又常常被簡稱為JSB,其實現原理可簡單地總結為:Cocos2d-x內置了一套JavaScript的解析引擎SpiderMonkey,通過SpiderMonkey在引擎內部將JavaScript代碼“映射”為C++代碼,從而實現了用JavaScript語法調用Cocos2d-x的API來完成遊戲的邏輯的編寫。這意味著,JSB開發模式在依然保持了C++原生應用同樣的性能這個優點之外,還大大降低了開發語言的門檻。

另外,由於Cocos2d家族的另一支新秀Cocos2d-HTML5也繼承了Cocos2d家族相同的API結構,這就使得我們可以將由JSB編寫的代碼很輕鬆地移植到Cocos2d-HTML5,從而實現了橫跨原生客戶端和瀏覽器的全新的遊戲開發模式。這一特性優勢,也是目前與JSB並行存在的Cocos2d-x Lua Binding所不能比擬的。雖然相比Lua Binding而言JavaScript Binding目前還顯得不太成熟,但我認為後者一定是未來。

在講述Cocos2d-x JavaScript Binding開發實踐之前,我們不得不提到CocosBuilder。相信很多人都至少聽說過這款功能強大的工具,其集成了所見即所得的場景編輯器、動畫編輯器、智能紋理打包以及JavaScript綁定相關配置功能,讓開發工程師不再需要跟任何視覺相關的環節打交道,從而專注於遊戲的邏輯控制部分,使得遊戲開髮變得更加簡單。下面就將結合我的實際使用經歷來講解Cocos2d-x JavaScript Binding結合CocosBuilder的跨平台遊戲開發實踐。

二、開發環境配置

本節內容我大量參考和翻譯了國外的一篇文章《Setup a cross platform project with CocosBuilder and Cocos2d-x》(須翻牆),這篇文章裡所描述的項目目錄結構較為合理,我個人認為非常適合用作跨平台開發和調試的通用結構。我將這篇文章的主要內容摘錄翻譯下來,並結合這篇教程的需要做了一些修改,同時也方便了英文不好的朋友。

1、在Mac終端下載Cocos2d-x最新版本並解壓(此時最新版本為2.1.4)。 我更習慣用命令工具列,參考下面:

$  cd #回到根目录,也可以放在别的目錄
$  wget https://cocos2d-x.googlecode.com/files/cocos2d-x-2.1.4.zip
$  unzip cocos2d-x-2.1.4.zip
提示:以上過程解壓後的目錄應該是cocos2d-x-2.1.4,你可能改下目錄名,也可以保持不變。下面的內容將會把這個目錄名用{cocos2d-x}代替。比如,我的{cocos2d-x}實際指代的是/Users/liusong/cocos2d-x

2、使用cocos2d-x自带的工具创建工程。

$  cd {cocos2d-x}/tools/project-creator
$  ./create_project.py -project MyGame -package com.MyCompany.AwesomeGame -language javascript  #創建一個名叫MyGame的跨平台工程,會在{cocos2d-x}/projects/目錄下自動生成MyGame工程代碼
$  cd ../../projects/MyGame  #切换到工程目錄
$  rm -rf Resources/     #刪除默認生成的資源目录,後面會用到CocosBuilder生成的資源目錄
提示:這裡創建的工程名稱MyGame會在後續教程中頻繁出現,如果你不是使用這個名稱,那麼請注意在後面自行更改

3、下載、安裝、配置CocosBuilder的最新版(此時最新版為3.0 alpha4)。

在這裡我推薦使用Git來clone源碼的方式來下載CocosBuilder,因為目前CocosBuilder尚在發展中,並不太完善和穩定,下載源代碼的好處是今後遇到問題時可以自己通過追蹤源代碼來解決,也可以及時合併最新的補丁而不用等官方發布新版。
$  cd #回到根目錄,也可以放在别的目錄
$  git clone https://github.com/cocos2d/CocosBuilder.git
$  cd CocosBuilder
$  git submodule update --init --recursive
$  open ./CocosBuilder/CocosBuilder.Xcodeproj  #打开CocosBuilder的Xcode工程

在打開的Xcode工程中,確認左上角的scheme是CocosBuilder而不是其他,直接點擊“Run”,經過一段時間的編譯運行後CocosBuilder將會被打開。這時候,你可以在CocosBuilder根目錄下的build文件夾中看到Xcode生成的CocosBuilder.app文件。今後如果有需要啟動CocosBuilder,就可以直接打開這個來啟動,無須再在Xcode中編譯運行,除非是你修改過CocosBuilder的源碼。這個我們後面會提到。 

在打開的CocosBuilder界面中新建一個CocosBuilder工程(File->New->New Project),注意這裡的命名一定和之前的項目名稱一樣,並且要保存在工程目錄。如下圖所示:

保存時會提示是否覆蓋,請點擊“Replace”確認覆蓋。如下圖:
提示:如果你操作時沒有出現這個提示,那麼一定是你的名稱或保存目錄位置有錯,請刪除剛才創建的內容重新操作。

以上操作完畢後,你會看到在MyGame目錄下新增了MyGame.ccbproj文件和Resources目錄。 MyGame.ccbproj是CocosBuilder的工程文件,而Resources則是默認的資源存放路徑。

還記得我們之前創建項目工程後刪掉的Resources目錄嗎?這裡又重新補上了,因為我們下來都要用CocosBuilder來組織和生成遊戲資源。注意這個資源路徑設置僅僅是默認的,為了方便教學我們不做修改,如果你需要修改,​​請打開菜單File->Project Settings進行修改。
打開Resources目錄可以看到,裡面已經有一些文件。這是CocosBuilder在創建工程時默認為我們添加的,我們這個教程將直接使用這些默認的資源來進行演示,所以我們予以保留。如下圖:

接下來,點擊菜單(File->Publish Settings)打卡發佈設置界面,激活所有平台。默認情況下,iOS和HTML5的發佈設置都是選中狀態,我們只需要再勾選上中間的Andr​​oid。請注意每個選項中以Published-開頭的設置,那代表著你用CocosBuilder製作的遊戲資源或代碼將會被存儲到那些對應的目錄裡。圖示:
最後點擊菜單(File->Publish)進行發布,這個發布行為會自動生成上面提到的三個Published-開頭的文件夾。打開看看,會發現裡面有一些文件,那都是剛才由CocosBuilder自動生成的。仔細觀察會發現,不同平台目錄下的文件會有所差異,這就是CocosBuilder的強大之處,它可以根據你的設置來針對不同平台的特徵自動處理資源兼容和適配問題。另外,原來資源目錄Resources下的ccb文件均被發布成了ccbi的二進製版本,以供程序代碼直接調用。


4、修改工程配置以連接CocosBuilder

修改AppDelegate.cpp
$  cd {cocos2d-x}/projects/MyGame #切换到项目根目錄
$  vim Classes/AppDelegate.cpp
最後,修改applicationDidFinishLaunching的內容如下:
bool AppDelegate::applicationDidFinishLaunching()
{
  // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());

    CCSize designSize = CCSizeMake( 480,320);
    CCSize resourceSize = CCSizeMake( 960,640);
    CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();

    std::vector<std::string> resDirOrders;

    TargetPlatform platform = CCApplication::sharedApplication()->getTargetPlatform();
    if (platform == kTargetIphone || platform == kTargetIpad)
    {
        std::vector<std::string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths();
        searchPaths.insert(searchPaths.begin(), "Published-iOS");
        CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
        if (screenSize.height == 1536)//iPad-hd
        {
            CCLog("resources-ipadhd");
            resourceSize = CCSizeMake(2048, 1536);
            resDirOrders.push_back("resources-ipadhd");
        }
        else if (screenSize.height == 768)//iPad
        {
            CCLog("resources-ipad");
            resourceSize = CCSizeMake(1024, 768);
            resDirOrders.push_back("resources-ipad");
        }
        else if (screenSize.height == 640)//iPhone 4/4s/5
        {
            CCLog("resources-iphonehd");
            resourceSize = CCSizeMake( 960,640);
            resDirOrders.push_back("resources-iphonehd");
        }
        else//iPhone 3GS
        {
            CCLog("resources-iphone");
            resourceSize = CCSizeMake(480, 320);
            resDirOrders.push_back("resources-iphone");
        }
    }
    else if (platform == kTargetAndroid || platform == kTargetWindows)
    {
        if (screenSize.height > 720)
        {
            resourceSize = CCSizeMake( 960,640);
            resDirOrders.push_back("resources-large");
        }
        else if (screenSize.height > 568)
        {
            resourceSize = CCSizeMake(480, 720);
            resDirOrders.push_back("resources-medium");
        }
        else
        {
            resourceSize = CCSizeMake(320, 568);
            resDirOrders.push_back("resources-small");
        }
    }

    CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(resDirOrders);
    pDirector->setContentScaleFactor(resourceSize.width/designSize.width);
    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);

    // turn on display FPS
    pDirector->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);

    ScriptingCore* sc = ScriptingCore::getInstance();
    sc->addRegisterCallback(register_all_cocos2dx);
    sc->addRegisterCallback(register_all_cocos2dx_extension);
    sc->addRegisterCallback(register_all_cocos2dx_extension_manual);
    sc->addRegisterCallback(register_cocos2dx_js_extensions);
    sc->addRegisterCallback(register_CCBuilderReader);
    sc->addRegisterCallback(jsb_register_chipmunk);
    sc->addRegisterCallback(jsb_register_system);
    sc->addRegisterCallback(JSB_register_opengl);
    sc->addRegisterCallback(MinXmlHttpRequest::_js_register);
    sc->addRegisterCallback(register_jsb_websocket);

    sc->start();

    CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();
    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
    ScriptingCore::getInstance()->runScript("main.js");

    return true;
}
全部修改完成後保存,退出編輯。

仔細對比不難發現,這裡所做的修改,是在應用啟動的時候根據設備類型和屏幕分辨率來設置資源搜索路徑。這個步驟的設置常常會被忽略掉,我本人也曾經在這裡浪費掉很多時間。究其原因,是CocosBuilder給人留下了“自動適配多種分辨率”印象,從而下意識地認為這個適配工作將會由引擎來自動完成,而實際情況卻不是這樣。

CocosBuilder可以以某個分辨率下的資源為準,通過自動縮放來為生成適配其他分辨率的資源,但遊戲中如何加載這些不同的資源卻需要手工設置規則。

修改iOS工程配置

$  open proj.ios/MyGame.Xcodeproj/ #打开iOS工程

打開後,分別做以下三件事:
可以看到Resources分組下的main.js, res, src是顯示紅色的,這些文件或文件夾在此前的步驟裡已經連帶Resources目錄刪除而不存在,但其引用關係依然在,所以我們將其選中並右鍵點選“delete”刪除。



將此前由CocosBuilder自動生成的Published-iOS文件夾拖拽到Xcode中。注意要放在MyGame的根節點下,並且要在彈出的窗口中去掉第一個"Copy items into …"選項前面的勾選狀態,然後選中“Create folder references for any added folders”。這兩個操作非常重要,其含義是在MyGame的Xcode工程中對Published-iOS文件夾建立一個“引用”關係,而不是將此文件夾的內容複製到工程中。這樣的好處是,今後Published-iOS目錄中有任何變動都會及時地反應到MyGame,而無須再次手動添加到工程。


注意Xcode左上角的scheme區域的左側,如果顯示的是cocos2dx,請點擊該按鈕將其手動改為MyGame。如果本就是MyGame則無須修改。另外,右邊的iOS Device也需要重新點選為一個具體的模擬器,如圖,我選擇的是iPhone 6.1 Simulator。


完成以上步驟後,點擊左上角Run按鈕,Xcode將會開始編譯並自動啟動模擬器來啟動和運行MyGame。看看效果,就是此前在CocosBuilder所生成的默認畫面。

修改Android工程配置[待更新,欢迎提交]


配置HTML5环境

HTML5版本中加載資源需要通過HTTP請求來完成,所以必須要有一個WebServer。你可以將Published-HTML5中的所有文件都上傳到你已有的服務器,也可以在本地搭建一個。本教程將不會涉及WebServer的內容,所以採用本地環境來搭建。 Python中有個快速搭建的命令:
$  cd {cocos2d-x}/projects/MyGame/Published-HTML5
$  python -m SimpleHTTPServer &
提示:python -m SimpleHTTPServer會在本機啟動一個WebServer,監聽8000端口,其默認目錄即是執行命令所在的當前目錄。因此註意要切換到你的Published-HTML5目錄下執行。

當屏幕出現類似如下提示時表示WebServer啟動成功:
Serving HTTP on 0.0.0.0 port 8000 ...

這時候打開瀏覽器,輸入http://localhost:8000即可在瀏覽器中啟動由CocosBuilder為我們自動生成的遊戲。

至此,我們的開發環境已經全部搭建完成,從此,我們就可以開始一種全新的、完全在CocosBuilder中進行遊戲開發的開發體驗了。接下來,我們會以CocosBuilder為MyGame工程默認創建的資源為基礎,通過示例講解如何在CocosBuilder中進行JSB的開發。

三、在CocosBuilder中進行遊戲開發

打開MyGame的CocosBuilder工程(也可以用圖形界面的菜單選項打開File->Open):
$  open {cocos2d-x}/projects/MyGame/MyGame.ccbproj

其界面大致介紹如下圖:

在左側的資源列表區,我們可以看到兩個以MainScene開頭的文件,一個是ccb,一個是js。
ccb文件類似PhotoShop的PSD文件,我們開發遊戲過程中的場景、精靈、動畫等都可以在ccb文件中進行編輯。另一個js文件無須多講,這就是遊戲的邏輯代碼,以JavaScript來編寫。

MainScene.ccb是CocosBuilder的默認入口,即遊戲啟動後第一個加載的場景。如果你想用其他文件作為默認入口,只需打開工程設置(File->Project settings)修改“Start ccb-file name”即可。在工程設置窗口,還可以看到其他選項,第一個“Resources paths”前面已經講過,設置資源路徑,第二個默認勾選的“JavaScript based project”表示是否使用JSB開發模式,如果你的遊戲不採用JSB,就可以去掉這個勾選。第三個默認入口已經講過,最後一個選項是設置遊戲支持的屏幕旋轉方向,默認是橫屏。

我們來到CocosBuilder界面中下面的編輯區,“Default Timeline”表示這是當前ccb的默認時間軸,點擊這裡會彈出新建和編輯timeline等選項,每個ccb文件都可以創建多個timeline,並且可以將多個timeline連接起來,具體可見點擊界面底部的“No chained timeline”的彈出菜單。


點擊選中CCLayer節點,右側會顯示這個層的各種屬性設置選項。我們注意到最頂部的“Code Connections”中“JS Controller”,這就是ccb文件和JavaScript自動連接的重要選項,它為當前這個層定義了一個JavaScript的控制器類的名稱,這樣我們就可以在程序代碼中來直接操作這個層裡面的資源或節點。

再往下,點擊選中CCLabelTTF節點,右側的“Code Connections”中“JS Controller”被禁用,第二個選項則定義了這個文本控件的名稱helloLabel。類似地,我們再選中最後一個CCMenuItemImage節點,這是一個按鈕控件,右側下面的CCMenuItem區域也已經為這個按鈕定義好了其點擊時觸發的方法名稱onPressButton,這樣我們也只需在JavaScript代碼中定義此方法即可。

在左側資源列表區雙擊打開MainScene.js,這裡的內容就可以看到MainScene的類定義、按鈕點擊​​時調用的onPressButton的方法定義及成員變量helloLabel的用法。到這裡,我們應該就基本明白了在CocosBuilder中進行遊戲開發的大致流程,我簡單總結如下:

1)在ccb中組織美術資源,創建動畫、特效
2)根據需要設置相關節點的屬性以備代碼連接
3)編寫JavaScript程序實現遊戲邏輯
4)發布,然後分別在Xcode、Eclipse和瀏覽器中調試結果

提示:以上第4步的調試工作也可以在CocosPlayer中進行,但CocosPlayer僅支持iOS和Android模擬器,考慮到HTML5平台調試的問題,本教程將暫不涉及CocosPlayer。

通常情況下,一個遊戲開發過程中有關場景、動畫和特效等視覺上的工作都是由團隊中的美術來負責完成的,因此ccb這些文件理論上來說應該由美術來完成編輯再交由開發工程師來調用,但我更推薦工程師也要學會使用CocosBuilder中場景、動畫和特效編輯等功能的用法,或者索性由二者共同完成。因為CocosBuilder目前尚不完善,美術在學習和使用過程中可能會遇到一些問題,另外資源的組織方式也是會對遊戲的性能產生影響的,這時候就需要工程師能夠協助把關,共同實現最優的解決方案。

看完了默認的示例,我們接下來將基於這個例子的資源和代碼逐步深入講解一些遊戲開發中常見問題的實現。

1、響應觸屏事件

觸屏事件是遊戲開發中必不可少的,是玩家和遊戲產生交互的基礎。我們將以MainScene為例來講解如何響應玩家的觸屏事件,目標是實現玩家點擊屏幕任意區域後在helloLabel這個文本區域內顯示其點擊位置的坐標。

需要特別強調下,一個已知的問題是Cocos2d-x和CocosBuilder中對於事件定義的標準存在差異,這導致了我們必須通過修改Cocos2d-x中CCBReader的源代碼才能正確地響應各種事件。具體修改方式如下:
$  vim {cocos2d-x}/extensions/CCBReader/CCLayerLoader.cpp

#define PROPERTY_TOUCH_ENABLED "isTouchEnabled"
#define PROPERTY_ACCELEROMETER_ENABLED "isAccelerometerEnabled"
#define PROPERTY_MOUSE_ENABLED "isMouseEnabled"
#define PROPERTY_KEYBOARD_ENABLED "isKeyboardEnabled"
替換為:
#define PROPERTY_TOUCH_ENABLED "touchEnabled"
#define PROPERTY_ACCELEROMETER_ENABLED "accelerometerEnabled"
#define PROPERTY_MOUSE_ENABLED "mouseEnabled"
#define PROPERTY_KEYBOARD_ENABLED "keyboardEnabled"

這個問題已經存在了較長的時間,但至今最新版本依然沒有得以解決。
做完以上修改後,我們回到CocosBuilder。雙擊打開MainScene.ccb,選中根節點(CCLayer),我們在右側最下面的CCLayer屬性設置中可以看到四個選項,其各自的含義解釋如下圖:

我們預期的是想讓MainScene響應觸屏事件,因此默認選項不用更改即可,其他三項鼠標事件、重力感應事件和鍵盤事件沒有用到則暫且不管。

現在來到代碼中,雙擊打開MainScene.js,在文件最後一行下面增加如下代碼:
MainScene.prototype.onDidLoadFromCCB = function()
{
    cc.log('MainScene ccb file has been loaded!');

    this.rootNode.onTouchesBegan = function( touches, event) {
        // 将触屏开始事件转发给控制器 (this)
        this.controller.onTouchesBegan(touches, event);
        return true;
    };

    this.rootNode.onTouchesMoved = function( touches, event) {
        // 将触屏移动事件转发给控制器 (this)
        this.controller.onTouchesMoved(touches, event);
        return true;
    };

    this.rootNode.onTouchesEnded = function( touches, event) {
        // 将触屏结束事件转发给控制器 (this)
        this.controller.onTouchesEnded(touches, event);
        return true;
    };
};

MainScene.prototype.onTouchesBegan = function(touches, event)
{
    // 修改文本内容
    this.helloLabel.setString("TOUCH START: "+parseInt(touches[0].getLocation().x)+", "+parseInt(touches[0].getLocation().y));
};

MainScene.prototype.onTouchesMoved = function(touches, event)
{
    // do some staff here
};

MainScene.prototype.onTouchesEnded = function(touches, event)
{
    // do some staff here
};

以上代碼中,onDidLoadFromCCB方法會在ccb文件加載完成後自動調用,類似iOS中的viewDidLoad。我們在onDidLoadFromCCB中分別將三種觸屏事件轉發給控制器自定義的方法去處理。在觸屏開始事件的處理方法onTouchesBegan中,我們將觸屏位置信息轉換成文本顯示在屏幕上,實現了我們的目標。另外兩個onTouchesMoved和onTouchesEnded暫時沒有用上,但我們應該能就此理解它們的用法了。

2、HTTP網路請求

為了更好地演示XMLHttpRequest的用法,我們利用前面配置HTML5環境時開啟的WebServer來提供一個HTTP服務接口,該接口直接返回一段JSON格式的字符串,JavaScript將在接收到接口返回的數據時進一步解析處理。

$  cd {cocos2d-x}/projects/MyGame/Published-HTML5
$  echo '{"data":"I am from the remote server"}' > test.json

以上操作在WebServer的根目錄創建了一個test.json文件,內容是一段JSON格式的文本。我們的目標是玩家點擊屏幕上的按鈕時向http://localhost:8000/test.json發起一個HTTP請求,並將返回數據中data字段的內容打印在屏幕上。

同樣,雙擊打開MainScene.js,將MainScene.prototype.onPressButton的方法修改如下:
// Create callback for button
MainScene.prototype.onPressButton = function()
{   
    // Rotate the label when the button is pressed
    //this.helloLabel.runAction(cc.RotateBy.create(1,360));

    //新增以下代碼
    var theHelloLabel = this.helloLabel;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState==4) {// 4 = "loaded"
            if (xhr.status==200) {// 200 = "OK"
                var response = JSON.parse(xhr.responseText);
                cc.log(response);
                theHelloLabel.setString(response.data);
            } else {
                cc.log("Problem retrieving JSON data:" + xhr.statusText);
            }
        }
    };
    //发起一个GET请求
    xhr.open("GET", "http://localhost:8000/test.json");
    xhr.send(null);
};

3、多分辨率適配方案[待更新,歡迎提交]
4、WebSocket[待更新,歡迎提交]
5、Plugin-X整合綁定[待更新,歡迎提交]
6、自定義第三方庫的綁定[待更新,歡迎提交]
7、在線資源更新解決方案[待更新,歡迎提交]

[cocos2dx-JSB篇]javascript裡使用XmlHttpRequest中文顯示成亂碼問題

文章撰寫日期︰2013/08/21 11:38
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題

這幾天遇到了使用XMLHttpRequest元件時,
C++傳來的UTF-8格式中文字到Javascript端產生亂碼,
但英文、數字沒問題的BUG。


二、解決辦法

PO文到官網論壇
網友建議重新編制成BASE64碼,
後來經cocos2dx開發者James Chen協助下,
修改了XMLHttpRequest.CPP檔
讓中文從C++端傳給Javascript端得以正常顯示。

[cocosBuilder篇]在timeline上添加使用Callbacks或Sound effects

文章撰寫日期︰2013/08/18 17:10
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

使用了cocosBuilder,
如何使用timeline上的Callbacks和Sound effects呢?
介面上找了半天,
都找不到添增的方式。

原來,
使用方式是按著mac的option鍵+滑鼠左鍵在Callbacks或Sound effects上添加。

[cocos2dx-JSB/HTML5篇]在各個瀏覽器上播放音檔

文章撰寫日期︰2013/08/18 13:31
文章修改日期︰2013/11/30 16:25
文章修改次數︰5
cocos2dx使用版本︰v 2.1.4 / v 2.1.5
cocosBuilder使用版本︰v 3.0 alpha 5

一、前言

Codec support in modern desktop browsers
Browser Ogg Vorbis MP3 WAV
FireFox 3.6+
Safari 5+
Chrome 6
Opera 10.5+
Internet Explorer 9 (beta)

由於每個瀏覽器能播放的音檔格式皆不同,
Cocos2d-HTML5 也幫我們處理了這個問題。

二、本文開始


以下文章來自raywenderlich

Gratuitious Music and Sound Effects

You’re pretty close to having a workable (but extremely simple) game now. You just need to add some sound effects and music (since what kind of game doesn’t have sound!) and some simple game logic.
這個遊戲就快要完成了(但貌似還非常簡單),現在你還需要做的就是替這個遊戲添加聲音和特效(哪個遊戲沒有特效!)和一些簡單的遊戲邏輯。

First, update Cocos2DSimpleGame\Src\resource.js to add the sound effects:
首先,先更新在Cocos2DSimpleGame\Src\resource.js裡的這個聲音特效檔︰

var dirArt = "Art/";
var dirSounds = "Sounds/";
 
var s_player = dirArt + "player.png";
var s_monster = dirArt + "monster.png";
var s_projectile = dirArt + "projectile.png";
 
var s_bgMusic = dirSounds + "background-music.mp3";
var s_bgMusicOgg = dirSounds + "background-music.ogg";
var s_bgMusicCaf = dirSounds + "background-music.caf";
 
var s_shootEffect = dirSounds + "pew-pew-lei.mp3";
var s_shootEffectOgg = dirSounds + "pew-pew-lei.ogg";
var s_shootEffectWav = dirSounds + "pew-pew-lei.wav";
 
var g_ressources = [
 
    {type:"image", src:s_player},
    {type:"image", src:s_monster},
    {type:"image", src:s_projectile},
 
    {type:"sound", src:s_bgMusic},
    {type:"sound", src:s_bgMusicOgg},
    {type:"sound", src:s_bgMusicCaf},
 
    {type:"sound", src:s_shootEffect},
    {type:"sound", src:s_shootEffectOgg},
    {type:"sound", src:s_shootEffectWav}
 
];

Note that both the background music and sound effects are each saved in three different formats: mp3, ogg, and wav. This is because not all browsers support all formats, so by adding all three we will have the highest possible chance of the player being able to hear something. Cocos2D will detect what the browser supports and use the appropriate file – as long as they have the same filename.
注意︰這邊看到每一個背景音樂、聲音特效都被分別儲存了3種格式︰mp3、ogg和wav。主要是因為並非每種瀏覽器都能播放所有的音檔格式,所以準備3種格式的音檔,最能確保聲音播放是沒問題的。Cocos2D會偵測使用者用的瀏覽器支援了哪種適合的檔案-只要檔名都一樣就找的到。

var audioEngine = cc.AudioEngine.getInstance();
This gets a global reference to the audio engine so you can use it later. Then add this line to the end of onEnter:
這行取得到公域參照︰audio引擎,因此接下來的code你可以開始使用這個物件。把這行加到onEnter函式的最後一行吧!

audioEngine.playMusic(s_bgMusic, true);
audioEngine.playEffect(s_shootEffect);
Save the file and refresh your browser, and now you should have some groovy tunes!
存檔,重整您的瀏覽器,現在您將聽到優雅動人的音樂!

備註︰
audioEngine.playMusic如果直接傳參數xxx.mp3,
Cocos2d-html5就不會自動的幫你找xxx.ogg檔播放。
請宣告變數
var s_bgMusic = "xxx.mp3";

再用
audioEngine.playMusic(s_bgMusic, true);
播放,
這樣才會在Firefox上自動找xxx.ogg檔播放。

三、我的試驗心得

使用playMusic()時,
Cocos2d-html5會幫我們在背後自動判斷該音檔是否能夠在瀏覽器播放,
假設現在我們要播abc.mp3,
Cocos2d-html5發現Firefox不能播mp3,
那麼Cocos2d-html5會再去找有沒有abc.ogg或abc.wav檔來播放。

但是,
cocos2d-html選擇前,
會先去resources-html5.js資源裡去找是否有宣告此資源可用

因此,
即使您有放置abc.ogg檔在資源目錄下,
但卻沒在resources-html5.js檔裡宣告。
Firefox仍會無法播音!

CocosBuilder3.0 Alpha5 目前仍沒有將ogg檔宣告進resources-htm5.js的資源檔中,這個問題會導致Firefox一直無法聽到音檔。唯一的做法就是去修改CocosBuilder源碼,請CocosBuilder輸岀HTML5資料夾時,也一併將ogg檔添加進resource-html5.js裡。

修改的方法(以CocosBuilder 3.0 Alpha5 為例)

在CocosBuilder源碼檔案CocosBuilder\Publishing\CCBPublisher.m裡

1. 60行: 函式initWithProjectSettings中
    // Setup extensions to copy
    copyExtensions = [[NSArray alloc] initWithObjects:@"jpg",@"png", @"pvr", @"ccz", @"plist", @"fnt", @"ttf",@"js", @"json", @"wav",@"mp3",@"m4a",@"caf", nil];
改成
    // Setup extensions to copy
    copyExtensions = [[NSArray alloc] initWithObjects:@"jpg",@"png", @"pvr", @"ccz", @"plist", @"fnt", @"ttf",@"js", @"json", @"wav",@"mp3",@"ogg",@"m4a",@"caf", nil];//添加ogg副檔

2. 774行: 函式publishGeneratedFiles中
if ([ext isEqualToString:@"plist"]) type = @"plist";
            else if ([ext isEqualToString:@"png"]) type = @"image";
            else if ([ext isEqualToString:@"jpg"]) type = @"image";
            else if ([ext isEqualToString:@"jpeg"]) type = @"image";
            else if ([ext isEqualToString:@"mp3"]) type = @"sound";
            else if ([ext isEqualToString:@"ccbi"]) type = @"ccbi";
            else if ([ext isEqualToString:@"fnt"]) type = @"fnt";
改成
if ([ext isEqualToString:@"plist"]) type = @"plist";
            else if ([ext isEqualToString:@"png"]) type = @"image";
            else if ([ext isEqualToString:@"jpg"]) type = @"image";
            else if ([ext isEqualToString:@"jpeg"]) type = @"image";
            else if ([ext isEqualToString:@"mp3"]) type = @"sound";
            else if ([ext isEqualToString:@"ogg"]) type = @"sound";//加入這行
            else if ([ext isEqualToString:@"ccbi"]) type = @"ccbi";
            else if ([ext isEqualToString:@"fnt"]) type = @"fnt";
編譯並執行CocosBuilder,
會發現輸岀的HTML5資料夾resources-htm5.js檔裡, 都含蓋.ogg檔了!

[Git篇]在Git上Discard修改

在StackOverFlow查到的指令
git clean -df & git checkout -- .

[cocos2dx-JSB篇]tool-project-creator無法Run創建岀來的Xcode專案

文章撰寫日期︰2013/08/17 16:48
cocos2dx使用版本︰v 2.1.4
cocosBuilder使用版本︰v 3.0 alpha 5

一、問題

今天遇到使用/Users/urname/cocos2d-x/tools/project-creator/create_project.py創建跨平臺專案時,遇到創建岀來的cocos2dx-JSP-Xcode專案無法在simulator和device Run的問題,編譯完後一直沒任何開啟simulator的動作,整個呆在那邊。

二、解決辦法

後來交叉查明後發現,
這個被create_project創建岀來的proj.ios專案裡面又吃了一個cocos2dx專案,
把它當成framework來用,
因此在編譯它時,最好不要又另外開啟一個同為cocos2dx的專案,
避免Xcode在編譯時,遇到找不到此專案檔導致無法編譯的問題。

[Android篇]在Android中使用Cocos2D-X + Box2D

cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1
來源網址
Cocos2d-x 结合Box2D开发Android游戏配置方法
先通过 create-android-project.sh 脚本创建一个新的 cocos2d-x for android 工程。注意,在执行该脚本前需要先对该脚本进行编辑,来设定 NDK_ROOT 和 ANDROID_SDK_ROOT 两个变量的值(在该脚本文件的最前面几行)。NDK_ROOT 变量用来指定你计算机上 android ndk 的安装位置;ANDROID_SDK_ROOT 变量用来指定你计算机上 android sdk 的安装位置。

        工程建立完毕后,会在和 create-android-project.sh 同目录下看到你刚刚新建的工程文件夹。这里我们假设我们刚刚建立了一个名为 Box2DTest 的工程。则工程目录机构如下:

                Box2DTest
                        --android
                        --Classes
                        --Resource

        Classes 文件夹下主要是 C++ 源代码文件,该文件夹是你主要编写逻辑的地方。Resource 文件夹是资源文件,例如图片素材、音效文件等资源文件都必须放到这个文件夹下面。当然,这篇日志不是讲 cocos2d-x 入门。而是讲怎样在 cocos2d-x 中使用 Box2D,所以这里我们主要要看的是 android 文件夹。

        android 文件夹下面是个标准的 android 工程。通过 Eclipse 可以方便的将该工程导入并运行。当我们编写完毕我们的 C++ 代码后通过执行 android 文件夹下的 build_native.sh 脚本,可以将我们编写的 C++ 代码连同 cocos2d-x 引擎以及其他一些库编译成 so 文件,以供 android 程序通过 jni 调用它们。

        默认的 cocos2d-x for android 工程并没有将 Box2D 物理引擎库引入到工程中。如果我们想要在我们的程序中使用 Box2D 引擎,我们需要对编译脚本进行一些设置。首先我们看看一个默认的 cocos2d-x for android 工程都有哪些编译脚本。

                Box2DTest
                        --android
                                --jni
                                        --Android.mk
                                        --Application.mk
                                        --helloworld
                                                --Android.mk

        mk 文件是 Android NDK 所使用的 make file 。一个标准的 cocos2d-x for android 工程默认有三个 mk 文件,这三个文件在编译 C++ 代码时起到重要的作用。而要在自己的工程中使用 Box2D 物理引擎,则需要对这三个 mk 文件进行编辑,否则无法编译通过。

        首先是 Box2DTest/android/jni/Application.mk 文件。这里我们需要关注的是 APP_MODULES 这个变量,这个变量后面的值是指定我们需要编译的模块的名称。默认是这样的:

               
 APP_MODULES := cocos2d box2d cocosdenshion game_logic game


        这里我们需要将 Box2D 模块加入,这样在编译 C++ 代码是,会将 Box2D 模块编译成为 so 库文件。加入后是这样的:

              
 APP_STL := stlport_static
                APP_CPPFLAGS += -frtti
               APP_MODULES := cocos2d box2d cocosdenshion game_logic game


       然后是 Box2DTest/android/jni/Android.mk 文件。这个文件我们需要检查 subdirs 这个变量。这个变量的值是指定一些公共库的头文件的目录位置。在这个变量中我们需要确保将 Box2D 的库目录放入了其中。加入后完整的 subdirs 变量的赋值语句是这样的:

            LOCAL_PATH := $(call my-dir)
            include $(CLEAR_VARS)

           subdirs := $(addprefix $(LOCAL_PATH)/../../../,$(addsuffix /Android.mk, \
           Box2D \
           cocos2dx \
           CocosDenshion/android \
 ))
       subdirs += $(LOCAL_PATH)/../../Classes/Android.mk                   $(LOCAL_PATH)/helloworld/Android.mk

       include $(subdirs)


        接下来是 Box2DTest/android/jni/helloworld/Android.mk 文件。在这个文件中我们主要编辑 LOCAL_C_INCLUDES 变量。该变量指定我们 C++ 源代码中 include 的头文件的查找位置。默认的 LOCAL_C_INCLUDES 赋值是这样的:

                LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../cocos2dx \
                    $(LOCAL_PATH)/../../../../cocos2dx/platform \
                    $(LOCAL_PATH)/../../../../cocos2dx/include \
                    $(LOCAL_PATH)/../../../../CocosDenshion/include \
                    $(LOCAL_PATH)/../../../Classes

        默认的  LOCAL_C_INCLUDES 并没有将 Box2D 的头文件目录加入进去,在这种情况下我们在自己的 C++ 源代码中引入 Box2D 的话是无法编译通过的。简便的方法是加入下面两个路径:

 
 LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game

LOCAL_SRC_FILES := main.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../cocos2dx \
                    $(LOCAL_PATH)/../../../../cocos2dx/platform \
                    $(LOCAL_PATH)/../../../../cocos2dx/include \
                    $(LOCAL_PATH)/../../../../ \
                    $(LOCAL_PATH)/../../../../Box2D \
                    $(LOCAL_PATH)/../../../Classes

LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI)) \
                -lcocos2d -llog -lgame_logic \
                -lbox2d 
            
include $(BUILD_SHARED_LIBRARY)

        加入这两个路径之后,我们要想在我们的 C++ 源代码中引入 Box2D 库的话,只需要在 C++ 源代码中加入这样的语句就可以了。

                #include  "Box2D/Box2D.h"

         这样我们就可以在享受 cocos2d 引擎给我们带来的开发便利的同时享受到 Box2D 物理引擎给我们带来的开发乐趣了。

[Android篇]建立一個cocos2D-Android專案

cocos2dx使用版本︰v 2.0.4
cocosBuilder使用版本︰v 2.0 alpha 1

一、前提

如果NDK是放在D槽
請先設定環變
export NDK_ROOT=/cygdrive/d/Android/cygwin/android-ndk-r8

二、步驟

  1. 創立一個cocos2Dx-Android專案

    先下在cocos2Dx目錄底下,
    輸入create-android-project.bat指令
    註︰不能在Cygwin環境下執行。使用前請先將create-android-project.sh和create-android-project.bat裡的預設目錄設好。
  2.  針對這個專案目錄內執行build_native.sh

    創建完後,
    針對這個專案目錄內執行build_native.sh
    即可完成Android專屬的cocos2D專案
    即可使用Eclipse匯入修改。

     3.如果org.cocos2dx目錄遺失

In cocos2d-x 2.0.3 ...Cocos2d-x Lib java files has been considered as a different project only So import that project in the eclipse
Lets make it Simple
  1. First Import the project in eclipse from this path - cocos2d-2.0-x-2.0.3/cocos2dx/platform/android/java
You will see libcocos2dx project in eclipse ...Keep this project open always otherwise your projects will give error on the syntax of library
  1. Run create-android-project
  2. Now Import the project which you have created and just Run (If you know the concept of isLibrary then that's how they are maintaining it now ..)
Also additional information to run build-native.sh from eclipse only , Right Click Project ->C/C++ Build Uncheck Use Default Build COmmand and add following bash ${workspace_loc:/YourProjName}/build_native.sh NDK_DEBUG=1 V=1
Good Luck ..If any question please feel free to ask


三、其它

無法在Visual Studio 2012 Express安裝Cocos2DX template
Editing InstallWizardForVS2012.js located in cocos2D\template\msvc
Line 92, replace vcprojects with vcprojects_WDExpress then run install-templates-msvc.bat and templates will be installed succesfully in VS 2012 Express.
var strDestFolder = FileSys.BuildPath(strValue, "vcprojects_WDExpress");

相關網址︰
1.
2. 跨平臺開發IOS & Android版(中文)
3. 跨平臺開發IOS & Android版(原文)
4. 設定Windows底下的開發環境
5. 建置Cocos2D-X並用Eclipse引入
6. 新建專案後不用COPY一堆Lib的做法
7.

[coco2dx-Android篇]添加NDK境變數


[cocosBuilder]Android端無法使用sub-ccb

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

一、問題

遇到了sub-ccb資源無法在Android讀取,
embeddedNode->setPosition(ccbFileNode->getPosition());這句報BAD_ACCESS的問題。

遇到這個問題幾乎可以說ccbReader沒有在Resources資源下找到欲使用的sub-ccb資源。

解釋一下我的資料結構,
右圖是我目前cocosBuilder的路徑狀況。

Brain.ccb裡面用了Cursor.ccb當成sub ccb,
但在Android裡卻因為這個路徑結構,
而導致無法找到Cursor.ccb,
IOS則是執行正常。


二、解決辦法

仔細與TestCpp示範專案比對後,
發現有一個核取方塊我打了勾(見下圖)︰
Flatten paths when publishing這個選項在官方文件的註釋如下︰
cocosBuilder的專案路徑預設是在Resources根目錄下,也就是說,倘若今天你有mySubDirectory/myImage.png要被cocosBuilder使用,在放置檔案時,你也不能放在mySubDirectory目錄底下,而是要直接放在Resources根目錄下。
如果要用相對位置的方法取得資源,那麼這個核取方塊要取消,而且在Xcode專案中,要使用藍色資料夾引用圖檔資源(如右)。

這麼做以後,Android也能找到Resources裡根目錄的資源了。

[cocos2dx]製作有邊框文字/圖片(Stroke Font)

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

一、前言

想要將CCSpirte或CCLabelTTF增加邊框,
該怎麼做?

二、本文開始

爬文至cocos2dx討論版後,
發現網友Alexandr Gerasimov熱心地將另一位網友cocos2d的code改成c++語法,
供我們使用。
但是我在使用時,
發現物件一旦被設定過AnchorPoint,
這個繪製岀來的邊框就會跑掉。
因此加了AnchorPoint的判斷,
更改的源碼如下︰

    static CCRenderTexture* createStroke(CCSprite* label, int size, ccColor3B color, GLubyte opacity)
    {
        
        CCRenderTexture* rt = CCRenderTexture::create(label->getTexture()->getContentSize().width + size * 2,
                                                      label->getTexture()->getContentSize().height+size * 2);
        CCPoint originalPos = label->getPosition();
        
        ccColor3B originalColor = label->getColor();
        
        GLubyte originalOpacity = label->getOpacity();
        
        label->setColor(color);
        
        label->setOpacity(opacity);
        
        bool originalVisibility = label->isVisible();
        
        ccBlendFunc originalBlend = label->getBlendFunc();
        
        ccBlendFunc bf = {GL_SRC_ALPHA, GL_ONE};
        
        label->setBlendFunc(bf);
        
        CCPoint bottomLeft = ccp(
                                 label->getTexture()->getContentSize().width * label->getAnchorPoint().x + size,
                                 label->getTexture()->getContentSize().height * label->getAnchorPoint().y + size);
        
        //原來沒有判斷AnchorPoint的寫法
        //  CCPoint positionOffset= ccp(   - label->getTexture()->getContentSize().width / 2,
        //                                  - label->getTexture()->getContentSize().height / 2);
        
        //SetAnchorPoint會影響到positionOffset,所以要做判斷
        CCPoint positionOffset = CCPointZero;
        if(label->getAnchorPoint().x == 0.5f){
            positionOffset.x = 0;
        }else if(label->getAnchorPoint().x == 0.0f){
            positionOffset.x =- label->getTexture()->getContentSize().width / 2;
        }else{
            positionOffset.x = label->getTexture()->getContentSize().width/2;
        }
        if(label->getAnchorPoint().y == 0.5f){
            positionOffset.y = 0;
        }else if(label->getAnchorPoint().y == 0.0f){
            positionOffset.y =- label->getTexture()->getContentSize().height / 2;
        }else{
            positionOffset.y =  label->getTexture()->getContentSize().height/2;
        }
        
        CCPoint position = ccpSub(originalPos, positionOffset);
        
        rt->begin();
        
        for (int i=0; i<360 data-blogger-escaped-for="" data-blogger-escaped-i="" data-blogger-escaped-label-="" data-blogger-escaped-needs="" data-blogger-escaped-optimize="" data-blogger-escaped-should="" data-blogger-escaped-that="" data-blogger-escaped-you="" data-blogger-escaped-your="">setPosition(
                               ccp(bottomLeft.x + sin(CC_DEGREES_TO_RADIANS(i))*size, bottomLeft.y + cos(CC_DEGREES_TO_RADIANS(i))*size)
                               );
            label->visit();
        }
        rt->end();
        
        label->setPosition(originalPos);
        label->setColor(originalColor);
        label->setBlendFunc(originalBlend);
        label->setVisible(originalVisibility);
        label->setOpacity(originalOpacity);
        
        rt->setPosition(position);
        //反踞齒
        rt->getSprite()->getTexture()->setAntiAliasTexParameters();
        
        return rt;
    }

結果如下

[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);
}
問題解決。