天天看點

cocos2d-x 血淚史(1) 先從helloworld 切換到menu 吧

就用我的這個猥瑣的這款打飛機的遊戲來說吧。其實在我看來微信打飛機弱爆了,就隻是3種類型的飛機在頂部随機位置出現然後随機速度往下掉撞到玩家控制的保證螢幕上隻有一發子彈的射彈速度固定的飛機就會gameover被擊爆就會加分然後分數傳到伺服器跟小夥伴們炫耀的遊戲,看,弱爆了把,一句話就說完了~

我是典型的過度複雜化設計的程式猿,什麼意思,就是程式越複雜越帶感,功能越複雜越帶感,代碼越亂越帶感,是以。。。 騷年們在看這套血淚史的時候要慎重啊,要保持着寫代碼萬事從簡的心态,忘掉一切雜念,不過度設計,寫出四兩撥千斤的代碼。

好吧,那麼到底有多複雜呢?

得有個遊戲主界面的菜單吧,得有個關卡設計吧,得有區域地圖世界地圖吧,得有個幾十種敵機類型各種套路的boss吧,主角飛機得有幾種供選擇吧,得有打怪更新出裝備吧,得有技能樹吧。。。 是不是感覺頓時高端大氣上檔次了呢~啊哈哈哈哈哈哈哈,是不是想說“卧槽這大制作啊”,好吧,那麼就從第一個主界面的菜單開始吧.

首先你的代碼沒做什麼修改的話運作出來應該是這樣的:

cocos2d-x 血淚史(1) 先從helloworld 切換到menu 吧

看起來挺不錯呢。

那麼來看下代碼把,項目裡面應該有這樣的檔案: 

AppMacros:  看剛開始的那大坨注釋,提供了兩種情況,這裡我們選第一種,就是固定的設計分辨率來對應多個不同分辨率的資源,也就是說寫代碼的時候始終認為所有裝置的分辨率都一樣的,就照這個分辨率寫就行了,資源可以準備多套。這樣做對碼農們來說太棒了,讓美工們準備多套資源去吧哇哈哈哈哈~。

因為我們這個是豎屏打飛機的遊戲,是以把裡面的那些分辨率改成豎屏,像這樣:

1 #ifndef __APPMACROS_H__
 2 #define __APPMACROS_H__
 3 
 4 #include "cocos2d.h"
 5 
 6 /* For demonstrating using one design resolution to match different resources,
 7    or one resource to match different design resolutions.
 8 
 9    [Situation 1] Using one design resolution to match different resources.
10      Please look into Appdelegate::applicationDidFinishLaunching.
11      We check current device frame size to decide which resource need to be selected.
12      So if you want to test this situation which said in title '[Situation 1]',
13      you should change ios simulator to different device(e.g. iphone, iphone-retina3.5, iphone-retina4.0, ipad, ipad-retina),
14      or change the window size in "proj.XXX/main.cpp" by "CCEGLView::setFrameSize" if you are using win32 or linux plaform
15      and modify "proj.mac/AppController.mm" by changing the window rectangle.
16 
17    [Situation 2] Using one resource to match different design resolutions.
18      The coordinates in your codes is based on your current design resolution rather than resource size.
19      Therefore, your design resolution could be very large and your resource size could be small.
20      To test this, just define the marco 'TARGET_DESIGN_RESOLUTION_SIZE' to 'DESIGN_RESOLUTION_2048X1536'
21      and open iphone simulator or create a window of 480x320 size.
22 
23    [Note] Normally, developer just need to define one design resolution(e.g. 960x640) with one or more resources.
24  */
25 
26 #define DESIGN_RESOLUTION_480X320    0
27 #define DESIGN_RESOLUTION_1024X768   1
28 #define DESIGN_RESOLUTION_2048X1536  2
29 #define DESIGN_RESOLUTION_1136X640    4    // iphone5
30 #define DESGIN_RESOLUTION_1366X768    8    // 16:9
31 
32 /* If you want to switch design resolution, change next line */
33 #define TARGET_DESIGN_RESOLUTION_SIZE  DESGIN_RESOLUTION_1366X768
34 
35 typedef struct tagResource
36 {
37     cocos2d::CCSize size;
38     char directory[100];
39 }Resource;
40 
41 static Resource smallResource  =  { cocos2d::CCSizeMake(320, 480),   "iphone" };
42 static Resource mediumResource =  { cocos2d::CCSizeMake(768, 1366),  "iphone5"   };
43 static Resource largeResource  =  { cocos2d::CCSizeMake(1536, 2048), "ipadhd" };
44 
45 #if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320)
46 static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(320, 480);
47 #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESGIN_RESOLUTION_1366X768)
48 static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(768, 1366);
49 #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536)
50 static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(1536, 2048);
51 #else
52 #error unknown target design resolution!
53 #endif
54 
55 // The font size 24 is designed for small resolution, so we should change it to fit for current design resolution
56 #define TITLE_FONT_SIZE  (cocos2d::CCEGLView::sharedOpenGLView()->getDesignResolutionSize().width / smallResource.size.width * 24)
57 
58 #endif /* __APPMACROS_H__ */      

由于最近土豪太多,是以打算用mediumResource 了,就用iphone5 的吧,等等,768*1366 是個啥,和筆記本分辨率一樣,iphone5 是640*1136 好麼,嗯。。。我想說的是。。。不要在意這些細節[猥瑣]。。由于上面指派給那個Resource 的directory 的值是iphone5 不是原來的ipad,那麼找到項目所在目錄,裡面有個Resources 檔案夾,把下面那個ipad 檔案夾重命名成 iphone5 就ok 了。

AppDelegate.h/.cpp:  一個繼承于cocos2d::CCApplication 的類,實作了applicationDidFinishLaunching, applicationDidEnterBackground 還有applicationWillEnterForeground 這三個在CCApplication 的父類CCApplicationProtocol 裡定義的的虛方法。嗯,光看名字也知道這幾個方法幹啥的。。。就像windows store app 的項目裡面有個叫App 的東西繼承于windows.ui.xaml.application 然後裡面有OnLauched, OnSuspending, OnActived 一個意思,跑題了?~....

然後applicationDidFinishLaunching 這個方法裡面有一大坨代碼,沒錯,這裡就是主要的地方了,首先把director 和那個View 關聯起來,然後根據AppMacros 裡定義的東西設定了designResolution,然後又根據螢幕大小設定了資源目錄,接着設定顯示fps,最後用director 的runWithScene 方法傳入個HelloWorldScene 的執行個體就跑起來了~

HelloWorldScene.h/.cpp:  這是個詭異的檔案,因為檔案名明明叫HelloWorldScene 怎麼着裡面也得有個叫HelloWorldScene 的class 吧,進去一看是個繼承于 CCLayer 的叫HelloWorld 的類。裡面有個靜态方法傳回個CCScene 的指針:

static cocos2d::CCScene* scene();      

然後去cpp 裡看下實作,是執行個體化了HelloWorld 這個Layer 然後把它加到(addChild) 剛剛執行個體化的一個CCScene,再傳回這個CCScene。。。 為啥要這麼做呢,為啥不建立個HelloWorldScene 繼承于CCScene 呢,根據我的初步判斷,寫demo 的人一定是偷懶了,想着幹脆弄個靜态方法一次把scene layer 什麼的全create 完得了于是就這樣了。。。。 其實後來想想,可能還想告訴我們這樣一個道理:當用到CCScene,CCLayer 什麼的不一定非要被繼承着用,直接拿來用往裡面塞東西就行了(喂,這叫什麼道理,這是道理麼,怎麼沒感覺到什麼教育意義呢)

HelloWorld 還有個virtual bool init() 方法,這個幹嘛的呢?進去一看,這什麼亂七八糟的,不過還好注釋很全,不過其實沒有注釋也不難了解。。。 就是調用addChild 方法給自己加了個關閉按鈕(MenuItem),還有一個叫Hello World 的Label,然後一張背景圖,沒什麼特别:

1 bool HelloWorld::init()
 2 {
 3    //
 4     // 1. super init first
 5     if ( !CCLayer::init() )
 6     {
 7         return false;
 8     }
 9     
10     CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
11     CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
12 
13     /////
14     // 2. add a menu item with "X" image, which is clicked to quit the program
15     //    you may modify it.
16 
17     // add a "close" icon to exit the progress. it's an autorelease object
18     CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
19                                         "CloseNormal.png",
20                                         "CloseSelected.png",
21                                         this,
22                                         menu_selector(HelloWorld::menuCloseCallback));
23     
24     pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
25                                 origin.y + pCloseItem->getContentSize().height/2));
26 
27     // create menu, it's an autorelease object
28     CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
29     pMenu->setPosition(CCPointZero);
30     this->addChild(pMenu, 1);
31 
32     /////
33     // 3. add your codes below...
34 
35     // add a label shows "Hello World"
36     // create and initialize a label
37     
38     CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE);
39     
40     // position the label on the center of the screen
41     pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
42                             origin.y + visibleSize.height - pLabel->getContentSize().height));
43 
44     // add the label as a child to this layer
45     this->addChild(pLabel, 1);
46 
47     // add "HelloWorld" splash screen"
48     // Change it to COCOS LOGO
49     CCSprite* pSprite = CCSprite::create("Logo.png");
50     pSprite->setScale(2.f);
51     // position the sprite on the center of the screen
52     pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
53 
54     return true;
55 }      

需要注意的是,init 方法是重寫的基類方法,是以務必調用下基類的init,就像上面那樣調用CCLayer::init(),也就是告訴我們如果以後繼承引擎裡的類并且重寫方法,不想覆寫原方法記得去做個調用,當然也有例外,貌似像那些以Delegate 結尾的類的一些虛方法必須重寫,不然會被引擎用assert 強制報錯...

main.h/.cpp:  這個就沒啥好說的了,執行個體化了上面的那個AppDelegate,然後設定在win32 下的FrameSize,這裡就改成768*1366 吧,還有個setFrameZoomFactor 方法的調用,如果運作起來感覺視窗太高了超出螢幕分辨率(你的筆記本或者程式猿專用工作站),把參數改小點就ok 了。還有最頂端那個// uncomment below line, open debug console 把它下面那幾行注釋去掉,運作的時候能看到debug 控制台,看到調用CCLog 打出來的東西。

=======================================好了,接下來就是見證奇級的時刻========================

==========================喂,說了半天隻是說原來項目template 生成的東西啊==========================

==============================說好的加Menu 什麼的呢======================================

===========================================吐槽為什麼會是這種格式,感覺根本停不下來啊============

一般情況下我們見到的大制作,都會剛開始給些個華麗的splash 界面,顯示下xxx 工作室,xxx 遊戲,xxx 顯示卡晶片标志,xxx 引擎什麼的,然後淡入淡出再搞個華麗的CG 還死活不讓你任意鍵繼續,那麼我們也來個華麗的“淡入淡出”~ 深入淺出什麼的就算了。。

HERES THE PLAN: 首先顯示下cocos2d-x 的logo,然後淡入淡出到我們的主menu。

so easy,從cocos2d官網上麻溜的弄下來張logo,然後放到Resources/iphone5 那個檔案夾(為什麼這裡用/ 而不用\,因為隻有windows 用\,日語作業系統還用¥呢!!喪心病狂!!是以為了避免移植到其他平台出問題,而且win32 下也是能認得/ 的,是以以後子目錄都用/ 了)

接下來把HelloWorldScene.cpp 裡面添加關閉按鈕那段注釋掉,helloworld 的label 那段也注釋掉,再把添加Sprite 的那個裡面的HelloWorld.png 換成我們的Logo.png,好了~ 編譯運作:

cocos2d-x 血淚史(1) 先從helloworld 切換到menu 吧

哈哈,看起來很屌的樣子,接下來就是淡入淡出什麼的了,留着下篇再說吧,lulu 睡了~

轉載于:https://www.cnblogs.com/strawhatboy/p/3523309.html

繼續閱讀