1、前提:html
完成Hello Game項目的建立編譯。android
具體參考:Cocos2dx.3x_Hello Game項目建立篇ios
2、本篇目標:windows
l 分析proj.win32工程的主要構成app
l 分析proj.android工程的主要構成eclipse
l 新建一個MyScene.cpp而後在遊戲中顯示出來編輯器
l 在android真機上運行查看效果工具
3、分析:性能
咱們遊戲開發一般是這樣的,首先在Microsoft Visual Studio 2012中proj.win32工程編寫代碼而且在windows上調試運行,當遊戲主體開發完成後,進行so文件的編譯打包,而後繼續在eclipse的proj.android工程中編寫少許的代碼完成遊戲在android平臺下的打包開發。this
l 分析proj.win32工程的主要構成
用Microsoft Visual Studio 2012打開proj.win32工程
組成:
整個hellogame的解決方案由hellogame、libbox2d、libcocos2d、libSpine四個工程項目構成。
一、Hellogame工程:遊戲主工程,咱們開發工做主要在這個工程中完成
二、libbox2d工程:模擬2D剛體物體的C++物理引擎,大名鼎鼎植物大戰殭屍、憤怒的小鳥等遊戲均有這個引擎的功勞
三、libcocos2d工程:這個不用說了,整個cocos2dx核心
四、libSpine工程:工具軟件支持庫
接下來主要對Hellogame工程的代碼進行解析,libbox2d工程在後面的物理引擎篇的時候在進行講解,至於其它2個工程在後續使用到的篇幅中在進行講解。
Hellogame工程的源代碼:
工程主要由src目錄下的AppDelegate.cpp、AppDelegate.h、HelloWorldScene.cpp、HelloWorldScene.h四個源文件和win32目錄下的main.cpp、main.h兩個源文件組成。
src目錄下的源文件是全部6個平臺共用的代碼文件,不論是android仍是ios都使用這個目錄下的源文件,屬於真正跨平臺部分的代碼。
win32目錄下的源文件只是一個main主入口文件,負責win32平臺下對遊戲的調用。其實在對應的proj.android的工程裏也有一個android平臺對應的main主入口文件,只是因爲平臺的不一樣實現代碼也各有不一樣,可是目的同樣。
AppDelegate.cpp源代碼:
AppDelegate相似於android的Application的做用,提供一些應用程序級別的狀態的回調,整個遊戲應用程序由這個文件方法進行控制。下面是幾個主要方法的說明和解釋:
#include "AppDelegate.h" #include "HelloWorldScene.h" //命名空間宏,偷懶引入cocos2d的頭文件 USING_NS_CC; AppDelegate::AppDelegate() { } AppDelegate::~AppDelegate() { } //設置 OpenGL context //這個設置對全部平臺都有效 void AppDelegate::initGLContextAttrs() { //設置 OpenGL context 屬性,目前只能設置6個屬性 //red,green,blue,alpha,depth,stencil GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8}; GLView::setGLContextAttrs(glContextAttrs); } //當應用程序啓動時執行,遊戲程序啓動入口 //在這裏咱們啓動了第一個scene(場景) //在具體遊戲中一般在這裏啓動loading界面 //你的遊戲從這裏開始! bool AppDelegate::applicationDidFinishLaunching() { // 初始化 director auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { glview = GLViewImpl::create("My Game"); director->setOpenGLView(glview); } // 在屏幕上顯示FPS數 // 開發階段建議開啓這個設置,能夠經過這個對本身遊戲性能有個大致瞭解 // 等遊戲正式發佈時關閉這個設置 director->setDisplayStats(true); // 設置 FPS數 默認值爲 1.0/60 director->setAnimationInterval(1.0 / 60); // 建立一個HelloWorld的scene.這個是自動回收的對象 auto scene = HelloWorld::createScene(); // 告訴director運行HelloWorld的scene director->runWithScene(scene); return true; } // 當遊戲進入後臺時會調用這個方法 // 好比玩遊戲時按下android手機的home按鍵 // 好比當遊戲時有電話打入直接顯示來電界面 void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation(); // 若是你的遊戲使用了SimpleAudioEngine,必須在這裏進行暫停 // 暫停代碼以下: // SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); } // 當遊戲恢復到前臺運行時會調用這個方法 // 好比接電話結束是遊戲界面又恢復到前臺時 void AppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation(); // 若是你的遊戲使用了SimpleAudioEngine, 必須在這裏進行恢復 // 恢復代碼以下: // SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); }
上述代碼解釋中的提到的director(導演:負責遊戲場景的顯示切換等,像電影導演同樣掌控整個電影的一切)、scene(場景:負責顯示一個遊戲場景,就像電影的一個場景鏡頭)。
上面代碼中最重要的方法爲applicationDidFinishLaunching(),由於你的遊戲從這個方法開始!
HelloWorldScene.cpp源代碼:
上面代碼中在AppDelegate類的applicationDidFinishLaunching()方法中建立了一個HelloWorldScene的場景,而且運行這個場景,HelloWorldScene.cpp就是這個場景具體的代碼實現。下面是幾個主要方法的說明和解釋:
#include "HelloWorldScene.h" USING_NS_CC; //建立場景 Scene* HelloWorld::createScene() { //建立一個自釋放的場景對象 auto scene = Scene::create(); //建立一個自釋放的畫面層對象 auto layer = HelloWorld::create(); //把建立的畫面層添加到場景中 //一個場景能夠添加多個畫面層 scene->addChild(layer); //返回這個建立的場景 return scene; } // 場景初始化方法 bool HelloWorld::init() { // 1. 首先進行父類初始化 if ( !Layer::init() ) { //若是初始化父類失敗返回false return false; } //獲取整個手機可視屏幕尺寸 Size visibleSize = Director::getInstance()->getVisibleSize(); //獲取手機可視屏原點的座標 Vec2 origin = Director::getInstance()->getVisibleOrigin(); // 建立一個帶圖標的關閉按鈕 // 點擊後調用menuCloseCallback方法退出遊戲 auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); // 設置關閉按鈕的顯示位置 // 顯示在可視屏幕的右下角 closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // 建立一個可自釋放的菜單 auto menu = Menu::create(closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1); //建立一個顯示"Hello Game"文字的Label auto label = Label::createWithTTF("Hello Game", "fonts/Marker Felt.ttf", 24); // 設置label在屏幕中的顯示位置 label->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + visibleSize.height - label->getContentSize().height)); // 把label添加到畫面層 this->addChild(label, 1); // 建立一個帶圖片的精靈 auto sprite = Sprite::create("HelloWorld.png"); // 設置圖片精靈的顯示位置 sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); // 添加圖片精靈到畫面層 this->addChild(sprite, 0); return true; } // 退出按鈕事件 void HelloWorld::menuCloseCallback(Ref* pSender) { //當是wp8或者winrt平臺的時候 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return; #endif //結束Director Director::getInstance()->end(); //當是ios平臺的時候退出 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif }
上述的代碼是一個簡單的Scene(場景)實現代碼,當咱們真正開發遊戲時,其實就是製做一個一個的場景,而且經過Director進行調度組織構成一個完整的遊戲。
l 分析proj.android工程的主要構成
用eclipse打開proj.android工程
組成:
整個hellogame的相比win32的要簡單多了,除了android項目必須的一些組成部分以外:
一、 Classes文件夾:這裏面的源文件和上面proj.win32中的屬於同一份共享。
二、 jni/hellocpp/main.cpp:這個至關於proj.win32中的win32目錄下的源文件,主入口。
三、 libs/armeabi/libcocos2dcpp.so:這個是整個遊戲代碼的編譯包,其實真正遊戲代碼實現都最終由C++文件編譯打包成這個so類庫供android代碼調用運行遊戲。
整個遊戲的開發基本上不須要在eclipse中編寫代碼,android平臺只須要調用編譯好的so文件便可運行遊戲,eclipse中只須要把包含了so文件的android工程打包成apk文件發佈便可。
l 新建一個MyScene.cpp而後在遊戲中顯示出來
用Microsoft Visual Studio 2012打開proj.win32工程,咱們將在這個工程裏新加一個本身的Scence(場景)而且顯示出來。這個看着是個很簡單的任務可是對新手來講仍是會碰到不少困難,因此這裏特別的作一下演示。
文件新建:cpp文件這裏有2個新建方法,
1、第一種方式
第一步:在右邊的解決方案資源管理器中右鍵src新建類。
問題:到這裏你會發現「瀏覽」按鈕不能夠用,新建的cpp只能新建到目錄hellogame\proj.win32下,這樣會致使一個問題。
第二步:先無論這個咱們按照提示繼續點擊「添加」進入類嚮導界面輸入類名MyScene而後點擊完成類的建立,這個時候在proj.win32目錄下新加MyScene.cpp和MyScene.h兩個文件。
2、第二種方式
第一步:在右邊的解決方案資源管理器中右鍵src新建項
問題:到這裏你會發現「瀏覽」按鈕能夠用,點擊修改一下目錄爲hellogame\Classes下,並且須要選擇是新建.ccp文件仍是.h文件.
第二步:這裏先選擇.cpp類型而後輸入MyScene.cpp而後完成建立,而後繼續前面的步驟新建MyScene.h文件。這個時候在Classes目錄下會出現新加的MyScene.cpp和MyScene.h兩個文件。
代碼編寫:
MyScene.h:
#include "cocos2d.h" class MyScene : public cocos2d::Layer { public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(MyScene); }; MyScene.cpp: #include "MyScene.h" USING_NS_CC; Scene* MyScene::createScene() { auto scene=Scene::create(); auto layer=MyScene::create(); scene->addChild(layer); return scene; } bool MyScene::init() { if(!Layer::init()) { return false; } //獲取整個手機可視屏幕尺寸 Size visibleSize = Director::getInstance()->getVisibleSize(); //獲取手機可視屏原點的座標 Vec2 origin = Director::getInstance()->getVisibleOrigin(); //建立一個顯示"MyScene"文字的Label auto label = Label::createWithTTF("MyScene", "fonts/Marker Felt.ttf", 24); //設置白色 label->setColor(Color3B::WHITE); // 設置label在屏幕中的顯示位置 label->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + visibleSize.height - label->getContentSize().height)); // 把label添加到畫面層 this->addChild(label, 1); return true; }
完成MyScene編寫後,咱們要先在遊戲開啓後的界面中添加一個按鈕菜單點擊後進入MyScene 場景。遊戲開啓後的界面場景是HelloWorldScene,因此咱們須要在HelloWorldScene中添加一個按鈕,而且爲這個按鈕添加一個點擊啓動MyScene的事件。
HelloWorldScene.h:
在這個文件中首先聲明一個按鈕點擊事件:
//切換到下一個scene事件
void menuNextCallback(cocos2d::Ref* pSender);
HelloWorldScene.cpp: 1、首先引入MyScene.h #include "HelloWorldScene.h" #include "MyScene.h" USING_NS_CC; …… 2、實現menuNextCallback事件代碼 // 按鈕點擊事件,點擊後啓動MyScene void HelloWorld::menuNextCallback(Ref* pSender) { //新建MyScene實例 auto scene = MyScene::createScene(); //用這MyScene實例替換當前scene Director::getInstance()->replaceScene(scene); } 4、 添加在屏幕上添加啓動按鈕 …… // 設置關閉按鈕的顯示位置 // 顯示在可視屏幕的右下角 closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // 新建一個帶圖片的按鈕菜單 auto goItem=MenuItemImage::create("next_1.png","next_2.png", CC_CALLBACK_1(HelloWorld::menuNextCallback, this)); goItem->setPosition(Vec2(origin.x + visibleSize.width/2 - closeItem->getContentSize().width/2 ,origin.y/2 + closeItem->getContentSize().height/2)); // 建立一個可自釋放的菜單 auto menu = Menu::create(closeItem,goItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1); ……
好了到此爲止咱們完成了全部代碼的編寫,如今開始調試運行查看一下效果。
問題:
這個時候若是你是用第二中方法建立的MyScene能正常編譯運行而第一種方法建立的MyScene會發沒法經過編譯沒辦法運行會報以下錯誤:
IntelliSense: 沒法打開 源 文件 "MyScene.h"
error C1083: 沒法打開包括文件:「MyScene.h」: No such file or directory
解決:
第一步:項目名點擊右鍵屬性
第二步:選擇左邊的C/C++而後在右邊的附加包含目錄追添加:;$(ProjectDir)
這個是我本人的附加包含目錄,每一個人環境不一樣應該有點區別
$(EngineRoot)cocos\audio\include;$(EngineRoot)external;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories) ;$(ProjectDir)
完成如上設置後在進行項目調試運行就能正常運行起來了,而且點擊按鈕後成功的顯示MyScene的畫面達到了咱們設定的目標。
l 在android真機上運行查看效果
要在android真機運行,首先須要進行so文件的打包編譯。
第一步:若是上面的步驟中是按照第一種方法建立的MyScene那麼請把MyScene.cpp、MyScene.h兩個文件從proj.win32文件拷貝到Classes文件夾下。若是是按照第二種方法建立的MyScene那麼能夠忽略本步驟。
第二步:用EditPlus等文本編輯器打開proj.android\jni目錄下的Android.mk文件,把MyScene.cpp添加到須要編譯的源文件清單中而後保存,以下:
……
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/MyScene.cpp
……
第三步:開啓Cygwin開始編譯打包so文件,若是不會請參考:Cocos2dx.3x_Hello Game項目建立篇
第四步:打包so文件成功後,而後開啓eclipse打開遊戲工程而且鏈接android手機運行工程看看真機運行的效果是否跟前面windows中的效果是否同樣。
結束語:
Cocos2d-x3.3入門三部曲到這裏就算是完成了,接下來將以具體一個遊戲爲一個系列的方式繼續深刻實戰,第一個實戰系列爲:《Cocos2d-x3.x塔防遊戲(保衛蘿蔔)從零開始》,這個系列總共有多少篇待定,目標是直到作完一個完整的符合上線標準的遊戲爲止絕非草草的練習之做。
做者交流QQ:2303452599
郵箱:mymoney1001@126.com