Cocos2D Buttons Tutorial for iOS: How To Create Buttons in Cocos2D: Simple, Radio, and Toggle

A Cocos2D buttons tutorial for iOS on how to create buttons in Cocos2D – normal push buttons, radio buttons, and toggle buttons. By Ray Wenderlich.

Leave a rating/review
Save for later
Share

Contents

Hide contents

Cocos2D Buttons Tutorial for iOS: How To Create Buttons in Cocos2D: Simple, Radio, and Toggle

10 mins

Buttons Tutorial Screenshot

Buttons Tutorial Screenshot

When you are making a game in Cocos2D, likely one of the first things you’ll find yourself needing is buttons. This Cocos2D buttons tutorial will show you how to create buttons in Cocos2D step by step, starting with simple buttons and then covering toggle and radio buttons too. This Cocos2D buttons tutorial assumes that you’ve already gone through the tutorial on how to create a simple game with Cocos2D, or have equivalent knowledge.

When I first started trying to add a button with Cocos2D, I thought the best way to was to just create a sprite representing the button and check for when the button was tapped. Although this is definitely possible, there’s a much easier way to create buttons in Cocos2D – by using the Cocos2D menu system.

The Cocos2D menu system consists of a menu that has a number of menu items inside it. Menu items can be either text or images, and the menu system contains logic for arranging menu items, highlighting items when they are tapped, toggling items, and more. So let’s give it a shot and try to create a simple button the Cocos2D way!

Creating A Simple Button

Create a new project in XCode using the cocos2d Application template, and name your project “CCButtons.” Next you need some images of buttons to work with – you can either use your own, or download some button images I have created. Once you have the images, drag them into your resources folder and make sure “Copy items into destination group’s folder (if needed)” is checked.

Open up HelloWorldScene.h under Classes and add a member variable to the HelloWorld class, we’ll need this in a bit:

CCLabelTTF *_label;

Then before we forget go to HelloWorldScene.m and add the cleanup code to the dealloc method:

[_label release];
_label = nil;

Ok now for the good stuff. In the same file (HelloWorldScene.m), replace the init method with the following code:

-(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;
}

First we create a label for debugging purposes. This should look pretty familiar – we did this in the last tutorial. However you’ll notice we’re using a new constructor this time that allows us to specify the dimensions of the label and the alignment. This way we specify the label size to be as wide as the window, and that the text should be centered. This is a handy technique to know, especially when you want to left or right justify text.

Next is the code where we create the button. We first create a menu item of class CCMenuItemImage and specify a selected and unselected image for the button. When we create the menu item, we specify a callback function to be called when the button is tapped (we’ll write this in a second). The last step is to create a menu to contain the button (or buttons).

Note that we create the menu at CGPointZero (a shortcut for 0,0). This is actually specifying where the center of the menu is. However, we also specify that the menu item is at offset (60, 60) relative to the center of the menu – so our button’s center is at (60, 60) on the screen.

Ok, one last bit of code to add. Underneath init add the callback function that will be called when the button is tapped:

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

Give it a compile and run, and if all goes well you should see the following:

Simple Button Screenshot

Toggle Buttons

Another common type of button you’ll need in an iPhone game is a toggle button. This is a button that has one image on it, until you tap it and it switches to another image. This could be used to toggle visibility of a control panel to make the best use of the limited screen real estate on the iPhone.

Luckily, Cocos2D comes with a special menu item class called CCMenuItemToggle that makes this easy. Let’s give this a shot! First add two more member variables to HelloWorldScene.h:

CCMenuItem *_plusItem; 
CCMenuItem *_minusItem;

And add the following cleanup code in your dealloc method:

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

Then add the following code in your init method right after you add the startMenu to the scene:

_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];

First we create two CCMenuItemImages, just like we did in our previous example. Then comes the twist – we add both of those into a CCMenuItemToggle. This class keeps toggles between the elements inside, and keeps track of which is currently visible.

Note that we set the callbacks to nil when we created the CCMenuItemImages, but set it on the CCMenuItemToggle. This is to make it clear that any selectors on the CCMenuItemImages will not be called when they are inside a CCMenuItemToggle – only the CCMenuItemToggle’s selector will be called. Luckily, we can easily tell which of the menu items is visible in the callback.

Let’s see how by writing the callback! Add the following after your init method:

- (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: -"];
  }  
}

So as you can see, the CCMenuItemToggle has a selectedItem property that can show us which of the sub-items is currently visible (note it means visible, not which was tapped!)

So give it a compile and run, and if all goes well you should see the following:

Toggle Button Screenshot