iPhone Coding Notes

~我的iPhone程式筆記~

用Menu建立遊戲主選單


前一陣子cocos2d for iphone團隊釋出了cocos2d v0.99穩定版,新增了不少功能,但也改了一堆指令。其中改變最大的就是幾乎所有類別的名稱,在0.99版中都加上了CC兩個字。比方Sprite就變成CCSprite,Layer變成CCLayer等,有興趣的朋友可以到這裡查看新版API的文件說。另外從這次開始,所有的教學都將以0.99版作為範例。所以還沒有更新的朋友,請趕快下載安裝吧~

這一次的教學主要是教大家如何利用cocos2d建立遊戲主選單,並連結該選單所要執行的動作。選單主要由CCMenu及CCMenuItem兩個類別物件組成。CCMenu是用來存放CCMenuItem的物件,CCMenuItem又可以分成CCMenuItemFont、CCMenuItemLabel等各種類型。我們只要依需求建立各類型的CCMenuItem物件,將他們放到Menu物件裡,最後把CCMenu物件加到CCLayer上,就大功告成了。

現在我們來試著建立幾個選單,同時當使用者按下第一個選單時,讓程式切換至cocos2d預設的HelloWorld頁面。

一樣先開啟Xcode並新建一個專案,如果已經安裝最新版的cocos2d的話,應該可以看到cocos2d 0.99的模版,點選它並命名為MenuTest。好了以後在視窗左欄Classes資料夾的地方按右鍵新增一個Objective-C class,把它命名為MenuScene,記得勾選「Also create MenuScene.h」讓Xcode自動新增MenuScene.h檔。我們將在MenuScene加入剛剛提到的CCMenu物件。

MenuScene.h和MenuScene.m的程式碼分別如下:

MenuScene.h

#import “cocos2d.h"

@interface MenuScene : CCLayer {

}

+ (id)scene;
@end

MenuScene.m

#import “MenuScene.h"
#import “HelloWorldScene.h"

@implementation MenuScene

+ (id)scene {
CCScene *scene = [CCScene node];
MenuScene *layer = [MenuScene node];

[scene addChild:layer];

return scene;
}

- (id)init {
if ((self = [super init])) {
[CCMenuItemFont setFontName:@"Helvetica"];

CCMenuItem *menuItem1 = [CCMenuItemFont
itemFromString:@"HelloWorld" target:self
selector:@selector(scene1:)];
CCMenuItem *menuItem2 = [CCMenuItemFont
itemFromString:@"Test"];

CCMenu *menu = [CCMenu menuWithItems:menuItem1, menuItem2,nil];

[menu alignItemsVertically];

[menu setPosition:ccp(240, 160)];

[self addChild:menu];
}
return self;
}

- (void)scene1:(id)sender {
[[CCDirector sharedDirector] replaceScene: [HelloWorld scene]];
}

- (void)dealloc {
[super dealloc];
}
@end

MenuScene.h檔的內容其實和模版預設的HelloWorldScene.h沒什麼不同,頂多只是類別名稱不同罷了。

至於MenuScene.m,我們把重點放在init函式上。在[super init]之後,首先看到的是

[CCMenuItemFont setFontName:@"Helvetica"];

這是用來設定CCMenuItemFont建立選單時所使用的字型。接著我們建立第一個CCMenuItem *menuItem1 :

CCMenuItem *menuItem1 = [CCMenuItemFont itemFromString:@"HelloWorld"
target:self selector:@selector(scene1:)];

這個CCMenuItem是用CCMenuItemFont類別建立的,它的好處是我們只要輸入該選單要顯示的字串就可以了,相反的,因為iPhone系統字型及顏色的限制,用這個方法建立的選單樣式相對比較單調。我們在itemFromString的地方填入「@"HelloWorld"」作為這個選單顯示的文字,target則填入self,最後selector的部份則輸入「@selector(scene1:)」。在@selector括號裡的函式名稱是用來表示當使用者按下這個選項時,所要連結並執行的函式,等等我們再去看scene1:這個函式做了什麼事情。

接著往下是另一個CCMenuItem *menuItem2,和上面一樣,我們使用CCMenuItemFont類別建立它,但因為我們不打算讓這個選項執行任何動作,所以後面target和selector的部份就省略了。

建立好CCMenuItem後,我們要將他們加到CCMenu裡去。建立一個CCMenu物件,並用menuWithItems:方法把剛剛建立的CCMenuItem加入,最後記得加入nil作為結束。下方可以看到一行[menu alignItemsVertically],這是用來排列剛剛加入的選項用的。如果要垂直排列,可以用alignItemsVertically;如果要水平排列,則是alignItemsHorizontally。

最後設定一下CCMenu物件的位置,並把它加入CCLayer裡,就完成了。

喔對了,還有一個scene1:函式沒講。當使用者按下「HelloWorld」選項時,程式會執行scene1:函式裡的指令。其實大家應該也都很熟悉

[[CCDirector sharedDirector] replaceScene: [HelloWorld scene]];

利用CCDirector把現在的CCScene換成HelloWorldScene,畫面就切換過去了。

好了,在編譯之前,最後一個小步驟,在MenuTestAppDelegate.m的開頭加入

#import “MenuScene.h"

接著往下找到

[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];

把它換成

[[CCDirector sharedDirector] runWithScene: [MenuScene scene]];

這樣程式一開始才會進入我們剛剛有建立選單的MenuScene畫面。

OK!按一下「Build and Run」看看是不是有順利進入選單,如果程式都沒有問題,按下「HelloWorld」後,應該就會看見HelloWorld的字樣了!


About these ads

6 responses to “用Menu建立遊戲主選單

  1. Lemon 2010/03/27 at 23:09:38

    請問我在遊戲裡面會有一些按鈕~~請問事都要用MenuItem寫嗎?

    • bonjouryentinglai 2010/03/27 at 23:32:36

      可以不用啊!MenuItem只是提供了一些方便的預設功能,像是可以直接設定按鈕「不按」,「按下」或「disable」時的對應圖檔,以及幫您排列MenuItem的位置,最重要的是,您不用自己寫touch event,只要設定這個MenuItem按下時對應的functioin即可。如果MenuItem的功能不能滿足您,那可以自己弄個CCSprite,然後當touch的點是在CCSprite裡時才發生對應的動作,不過touch event要自已寫,按下去CCSprite的圖檔改變也要自己,自由度高,相對也比較麻煩,大概是這樣,希望有回答到您的問題。
      寫到這我才想到,我好像沒教怎麼在cocos2d裡寫touch event 囧rz,真糟糕,有空我會盡快補上!

  2. Lemon 2010/03/30 at 13:41:01

    請問在
    CCMenuItem *menuItem1 = [CCMenuItemFont itemFromString:@"HelloWorld"target:self selector:@selector(scene1:)];

    我在selector(scene1:這裡可以傳值嗎?)

    因為它會call一個function我想傳值進去~請問要怎麼做?

    謝謝

    • bonjouryentinglai 2010/03/30 at 22:45:00

      這問題考倒我了,今天在網路上搜尋了一下,好像沒找到相關的用法。如果是我,會試著改用別的寫法來達到需要的功能。或者,是否有高手知道這個問題該怎麼辦呢?

    • Can 2010/07/30 at 02:12:25

      沒辦法傳值…..所以我用的方式是定義一個變數,然後那個函式去找那個變數,不過這有風險,因為我故意弄0.01 秒變動一次變數….跑個一陣子後,如果突然有什麼event~會亂掉….

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s

關注

Get every new post delivered to your Inbox.

%d bloggers like this: