(譯)在cocos2d裏面如何製做按鈕:簡單按鈕、單選按鈕和開關按鈕

 免責申明(必讀!):本博客提供的全部教程的翻譯原稿均來自於互聯網,僅供學習交流之用,切勿進行商業傳播。同時,轉載時不要移除本申明。如產生任何糾紛,均與本博客全部人、發表該翻譯稿之人無任何關係。謝謝合做! php

原文連接地址:http://www.raywenderlich.com/414/how-to-create-buttons-in-cocos2d-simple-radio-and-toggle html

程序截圖: app

  當你在使用cocos2d製做一個遊戲的時候,你極可能會發現,你須要的第一個東西就是「按鈕」。(好比遊戲開始時的菜單選擇界面等)這個教程將會一步步地教你如何使用cocos2d來建立按鈕。剛開始建立簡單的按鈕,而後再介紹開關按鈕和單選按鈕。這篇教程假設你已經閱讀了《如何使用cocos2d來製做簡單的iphone遊戲》這一系列的教程,或者具有同等相關經驗。 iphone

  當我第一次想要在cocos2d裏面添加一個按鈕的時候,我是這樣想的:建立一個精靈(sprite)來表明按鈕,而後檢測這個按鈕何時被按下去。固然,這樣作確定是可行的。可是,在cocos2d裏面,還有更簡單的方法--經過使用cocos2d的菜單系統。 ide

  在cocos2d的菜單系統裏面,包含一個menu,在menu裏面又包含一系列的menuitems。Menu items能夠是文本或者圖片,並且菜單系統裏面還包含了一些很是有用的邏輯,好比:排列菜單項(menu item),高亮顯示被按下去的菜單項,開關菜單項等等。好了,讓咱們實踐一下,看看用cocos2d的方式如何建立一個簡單的按鈕! 函數

建立一個簡單的按鈕

  打開Xcode,使用cocos2d Application template建立一個新的工程並命名爲:CCButtons。接下來,你須要一些按鈕的圖片--你能夠本身建立,或者下載一些我已經作好的圖片。好了,如今你有圖片了,把它們拖到resource文件夾下面,同時確保選中「 Copy items into destination group’s folder (if needed)」。 佈局

  打開Classes分組下面的HelloWorldscene.h文件,而後在HelloWorld類裏面添加一個成員變量,後面將會用到它: 學習

CCLabelTTF  * _label;

  而後,爲了防止忘記內存清理操做,打開HelloWorldScene.m並在dealloc方法中添加一些清理的代碼: ui

 

[_label release];
_label 
=  nil;

  好了,接下來就是重點了。一樣,在HelloWorldScene.m文件中,用下面的代碼替換掉init方法: google

複製代碼
- (id) init
{
if ( (self = [super init] )) {

CGSize winSize 
=  [[CCDirector sharedDirector] winSize];

//  Create a label for display purposes
_label  =  [[CCLabelTTF labelWithString: @" Last button: None "  
dimensions:CGSizeMake(
320 50 ) alignment:UITextAlignmentCenter 
fontName:
@" Arial "  fontSize: 32.0 ] retain];
_label.position 
=  ccp(winSize.width / 2
winSize.height
- (_label.contentSize.height / 2 ));
[self addChild:_label];

//  Standard method to create a button
CCMenuItem  * starMenuItem  =  [CCMenuItemImage 
itemFromNormalImage:
@" ButtonStar.png "  selectedImage: @" ButtonStarSel.png "  
target:self selector:@selector(starButtonTapped:)];
starMenuItem.position 
=  ccp( 60 60 );
CCMenu 
* starMenu  =  [CCMenu menuWithItems:starMenuItem, nil];
starMenu.position 
=  CGPointZero;
[self addChild:starMenu];

}
return  self;
}
複製代碼

  首先,爲了調試方便,咱們建立了一個label。這個看起來很熟悉對不對?---咱們在上一篇教程中有提到過。然而,這一次咱們使用了一個新的構造函數,它可讓咱們指定label的大小和文字對齊方式。在這裏,我把label的大小設置和窗口大小同樣寬,並且文本須要居中對齊。這是一種廣爲人知的技術了,特別是當你想實現一些左對齊或者右對齊的文本的時候。

  接下來的代碼是建立按鈕。首先使用類CCMenuItemImage來建立一個菜單項,併爲這個按鈕指定一張被選中的圖片和沒有被選中的圖片。(也就是單擊時被顯示的圖片和沒有被單擊時被顯示的圖片)當建立完菜單項以後,咱們爲按鈕的點擊事件指定了一個回調函數(這個函數後面會給出代碼)。最後一步,就是建立一個菜單來包含這個按鈕(或者一系列的按鈕,以nil結尾)。

  注意,咱們在CGPointZero(原點)的位置建立了按鈕。這裏實際上指定了菜單的中心點的位置。而後,咱們指定菜單項的位置相對於菜單的位置偏移(60,60)--這樣的話,在屏幕上面顯示的時候,菜單項就會顯示在(60,60)的位置了。(由於菜單項的position是相對於菜單的中心點來的,把菜單的中心點設置爲(0,0),與屏幕座標原點重合後,能夠方便爲每一個菜單項指定座標點,由於這時候,只要按鈕實際屏幕出現的位置設置菜單項的座標點就好了)。

  好了,還有一些代碼須要補充。在init方法後面,添加咱們的按鈕回調函數:

-  ( void )starButtonTapped:(id)sender {
[_label setString:
@" Last button: * " ];
}

  編譯並運行,你會看到以下的運行結果:

開關按鈕

  另一種在iphone遊戲裏面經常使用的按鈕類型就是--開關按鈕。這種類型的按鈕一次只有一個圖片顯示出來,當你單擊它的時候,它就會切換到另一張圖片。這個能夠用來製做一個控制面板的可見性的控制器,這樣能夠最大限度地利用iphone上面有限的屏幕大小。

  很是幸運的是,cocos2d裏面就內置了一種特殊的menu item叫作CCMenuItemToggle,它可使事情變得更加簡單。讓咱們來體驗一下吧!首先,在HelloWorldScene.h裏面添加2個成員變量:

CCMenuItem  * _plusItem; 
CCMenuItem 
* _minusItem;

  而後在dealloc方法裏面添加下面的清理代碼:

[_plusItem release];
_plusItem 
=  nil;
[_minusItem release];
_minusItem 
=  nil;

  而後,在你爲場景添加的StartMenu後面,再添加下面的代碼:

複製代碼
_plusItem  =  [[CCMenuItemImage itemFromNormalImage: @" ButtonPlus.png "  
selectedImage:
@" ButtonPlusSel.png "  target:nil selector:nil] retain];
_minusItem 
=  [[CCMenuItemImage itemFromNormalImage: @" ButtonMinus.png "  
selectedImage:
@" ButtonMinusSel.png "  target:nil selector:nil] retain];
CCMenuItemToggle 
* toggleItem  =  [CCMenuItemToggle itemWithTarget:self 
selector:@selector(plusMinusButtonTapped:) items:_plusItem, _minusItem, nil];
CCMenu 
* toggleMenu  =  [CCMenu menuWithItems:toggleItem, nil];
toggleMenu.position 
=  ccp( 60 120 );
[self addChild:toggleMenu];
複製代碼

  首先,  就像咱們前一個例子中同樣,建立兩個CCMenuItemImage。這裏有一點不一樣--我把它們都添加到了CCMenuItemToggle裏面。這個類會管理當前應該顯示的菜單項,同時會在開關元素之間進行一些切換。

  注意,當建立CCMenuItemImage的時候,我把回調函數設置成了nil,可是我爲CCMenuItemToggle類設置了回調函數。這樣,就會使得代碼意途更加清晰:當CCMenuItemImage在CCMenuItemToggle中的時候,在CCMenuItemImage上的任何selector都不會被調用,而只有 CCMenuItemToggle的selector會被調用。固然,咱們能夠很容易地在回調函數裏面區分,到底哪一個菜單項是可見的。

  接下來,讓咱們看看如何實現回調函數吧!在init方法後面添加下面的代碼:

複製代碼
-  ( void )plusMinusButtonTapped:(id)sender { 
CCMenuItemToggle 
* toggleItem  =  (CCMenuItemToggle  * )sender;
if  (toggleItem.selectedItem  ==  _plusItem) {
[_label setString:
@" Visible button: + " ]; 
else if  (toggleItem.selectedItem  ==  _minusItem) {
[_label setString:
@" Visible button: - " ];

}
複製代碼

  所以,正如你所見,CCMenuItemToggle裏有一個selectedItem屬性,它能夠告訴咱們它的哪個子菜單項當前可見(注意,當前可見的不等於被單擊的)

  好了,讓咱們運行一下吧!你會看到以下結果:

單選按鈕

  第三種經常使用的按鈕類型就是單選按鈕(radio button).我在作一個遊戲的時候,發現本身須要一些單選按鈕,可是,cocos2d的源代碼裏面並無任何有關單選按鈕的實現。所以,咱們本身實現一個單選按鈕。而後,當我在寫這篇教程的時候,我發現另外兩我的也寫了一些《在cocos2d裏面如何支持單選按鈕》的文章--這意味着,在不久的未來,你將會在cocos2d的源文件裏面看到有關單選按鈕的實現。

  可是,目前cocos2d裏面仍是沒有,所以,在這期間,你能夠免費地使用我上面提到的一些實現。這篇教程使用的是我本身寫的單選按鈕的實現。首先,下載CCRadioMenu.h和CCRadioMenu.m,而後把它們拖到你的Classes分組下面(確保複選「」)。而後在HelloWorldScene.m的頂部添加下面代碼:

#import  " CCRadioMenu.h "

  而後,在init方法後面,緊跟你添加開關按鈕的代碼,添加下面代碼:

複製代碼
CCMenuItem  * menuItem1  =  [CCMenuItemImage itemFromNormalImage: @" Button1.png "  
selectedImage:
@" Button1Sel.png "  target:self selector:@selector(button1Tapped:)];
CCMenuItem 
* menuItem2  =  [CCMenuItemImage itemFromNormalImage: @" Button2.png "  
selectedImage:
@" Button2Sel.png "  target:self selector:@selector(button2Tapped:)];
CCMenuItem 
* menuItem3  =  [CCMenuItemImage itemFromNormalImage: @" Button3.png "  
selectedImage:
@" Button3Sel.png "  target:self selector:@selector(button3Tapped:)];
CCRadioMenu 
* radioMenu  =  
[CCRadioMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];
radioMenu.position 
=  ccp( 120 180 );
[radioMenu alignItemsHorizontally];
radioMenu.selectedItem 
=  menuItem1;
[menuItem1 selected];
[self addChild:radioMenu];
複製代碼

  首先,像以前同樣,建立CCMenuItemImage,可是咱們不是把它加到CCMenu類中,而是把它們加到CCRadioMenu類中。這個類確保一次只有一個菜單項被選中。這裏,咱們設置默認狀況下,第一個菜單項被選中。

  這裏有一個新的知識點:咱們利用cocos2d裏面的本身佈局功能,調用menu的alignItemsHorizontally來水平對齊menu中的全部菜單項。注意,菜單項是相對於菜單的中心點來佈局的。所以,咱們再也不須要把菜單的中心點設置爲(0,0)了--取而代之的是,咱們須要把菜單往中間靠右挪動一些,這樣咱們就可讓菜單項都完整地顯示出來。

  最後一件事情--像以前同樣添加回調函數:

複製代碼
-  ( void )button1Tapped:(id)sender {
[_label setString:
@" Last button: 1 " ];
}

-  ( void )button2Tapped:(id)sender {
[_label setString:
@" Last button: 2 " ];
}

-  ( void )button3Tapped:(id)sender {
[_label setString:
@" Last button: 3 " ];
}
複製代碼

 

編譯並運行,你將會看到下面的結果:

背後的原理

  若是你看一看菜單系統是如何實現的,你會注意到全部的菜單項都是CCNode的子類,可是Menu是CCLayer的子類。根據cocos2d最佳實踐,你不該該建立很是大的層次結構,你應該讓層次結構儘量的小。

  所以,這意味着,你可能須要把儘量多的菜單項放到一個菜單裏面。由於,CCLayer是從CCNode派生出來的,它也能夠run action。就是說,你能夠對menu run action。

總結

  這裏有這個教程的完整的所有源代碼。但願這個教程對你有幫助,若是你在使用cocos2d的button的時候有什麼好的意見或好點子,請跟我分享!

相關文章
相關標籤/搜索