Archive

Posts Tagged ‘Cocoa Touch’

Labels, Menus, and Options in Cocos2d-iPhone

June 1st, 2009 beardo No comments

In my previous post I indicated that I was using the Cocoa Touch framework to do my menus and was having that interact with the Cocos2D-iPhone framework that I was doing to implement the actual game. This was a big mistake. After trying to get it all to interact correctly, I realized that I was “doing it wrong”. I ended up with a solution that added a blank UIView to the window, and then had to load up the other views. It was a mess and I still had the problem of the UIView overlay screwing up the touch events in Cocos2D-iPhone.

After decided there had to be a better way, I looked into the menu API in Cocos2D-iPhone. Turns out it is much easier, but to get good looking menu’s I’d need some more art. There are a few ways to make a menu with the API. First you can just use text and specify the menu name with a string. This is okay, but it really should look better for a game. Secondly, and the route I chose, is you can use images to display menu options. First I created some the images in Inkscape:

options_n

options_s

options disabled



The first image is the default display, second the image to display when selected (i.e. touched) and finally when the menu item is disabled. Here’s how to create a simple menu with these images:

/* Utility method to create a menu item assuming a naming convention */
- (MenuItemImage *)createMenuItem:(NSString *)prefix selector:(SEL)selector
{
	NSString *normal = [prefix stringByAppendingString:@"_n.png"];
	NSString *selected = [prefix stringByAppendingString:@"_s.png"];
	NSString *disabled = [prefix stringByAppendingString:@"_d.png"];

	MenuItemImage *result = [MenuItemImage itemFromNormalImage:normal
                                            selectedImage:selected
                                            disabledImage:disabled target:self selector:selector];

	return result;
}

// event handler...
-(void)showOptions:(id)sender
{
  [[Director  sharedDirector] pushScene:[OptionsMenuScene node]];
}

- (id) init {
    self = [super init];
    if (self != nil) {

      MenuItemImage *options = [self createMenuItem:@"options"
                                            selector:@selector(showOptions:)];
      Menu *menu = [Menu menuWithItems:optionsItem, nil];
      [menu alignItemsVertically];
      [self addChild:menu];
    }
}

It’s just that easy. I create a MenuItemImage using the three images, add it to a menu, and then add the menu to my scene. This example also takes advantage of the Menu class’s built-in layout facility. The event handler simply pushes another menu scene onto the scene stack. The documentation suggests that you avoid using the scene stack to save on memory, but I simply use it for the menus and it never gets more than 3 deep.

I also replaced the score display with a simple label:

scoreLabel_ = [Label labelWithString:@"Score: " dimensions:CGSizeMake(150,30)
                    alignment:UITextAlignmentLeft fontName:@"Helvetica"
                    fontSize:20.0];
[scoreLabel_ setRGB:0 :0 :0];
[scoreLabel_ setPosition:ccp(80, 300)];
[layer addChild:scoreLabel_];

// Then later to set the score:
[scoreLabel_ setString:[NSString stringWithFormat:@"Score: %d", score]]; 

The only thing interesting here is that I specify the width of the label, and make it left justified so that it renders how I need it to.

The last thing I did this weekend was to load and save game options. I used the built-in NSUserDefaults class to store and load the preferences. There are tons of examples out there, so I won’t bother repeating it here. I only have 7 more items on the list before I’m ready to release. Mostly it’s just some game mechanics and hooking up some more menus. I’m pumped.

Knocking on the door to success?

May 26th, 2009 beardo No comments

Got two opportunities over the long weekend to work on uSightRead. As of last night, the basic game works like a champ. Notes fly by, and the player must hit the correct note at the right time, and boom, they get points. I spent some time refactoring the code to support ledger lines for notes outside the staff. These are just sprites that follow along with the notes that are already there. The other thing I added was an overlay using Cocoa Touch. The overlay contains the score label, and a button for opening the settings.

I could have done the score and button with the Cocos2D-iPhone framework, but I didn’t really see anything that supported a button without having to build it up myself. I did find the Label class, so that would have worked for the score, but it seemed simpler to use Cocoa Touch. The one issue I had was if the UIView covered the entire surface, it would to throw off the touch handling withing Cocos2D-iPhone. To solve this, I simply made the UIView only take up the top 35 pixels of the app.

The only things left for the 1.0 release are to build the options/preferences menu, saving of those preferences (and high scores) and then some simple clean up of game mechanics (starting a new game, etc). I plan on releasing the 1.0 version and then providing free updates with new features. Lots of ideas, just not a ton of time to implement them. Hopefully by the end of the week I can have it submitted to the iTunes store and the button on the right will actually work :)