Cocos2d menu programming *without* images - cocos2d-iphone

Good evening all,
I'm trying to code a menu, but I keep getting
Thread 1: Program received signal: "SIGABRT".
My code is minimal at the moment, just trying to get it to work!
#implementation Menu
+(id)scene{
CCScene *scene = [CCScene node];
CCLayer *layer = [Menu node];
[scene addChild:layer];
return scene;
}
-(id)init{
if((self = [super init])){
CCLabelTTF *playLabel = [CCLabelTTF labelWithString:#"Play" fontName:#"Marker Felt" fontSize:40];
CCMenuItemLabel *play = [CCMenuItemLabel itemWithLabel:playLabel target:self selector:#selector(doPlay:)]; //This is where SIGABRT happens//
menu = [CCMenu menuWithItems:play, nil];
[self addChild:menu];
}
return self;
}
-(void)doPlay{
CCLOG(#"doPLay");
}
#end
Any help would be greatly appreciated :)
There seems to be quite little on coding menus without images.

First order of business:
Go to Build Settings
Locate the compiler warning flag "Undeclared Selector"
Set it to YES
This will catch a lot of similar errors, and I really don't understand why this setting isn't turned on by default in all Xcode projects.
Let me explain what your error is, it's easy to overlook without that warning enabled. The selector passed to menu item is this:
#selector(doPlay:)
The selector that's implemented is this:
-(void) doPlay
{
}
They don't match! The menu item is expecting a selector that takes one parameter, as denoted by the : (colon). Change selector to this:
#selector(doPlay)
You'll be fine. Next time, the compiler will warn you about that mishap.

Related

Cocos2d layer and touches priority management

I have my main scene, above it i set a new layer with CCLayer ,this layer has a button.
but when i hit that button (CCMenu), the layer behind it is also get the touches and do stuff.
I want to enable ONLY the upper layer touches, not the one under it .
How can i do that ? (setting touch priority ? how ? )
edit:
my layer is like that :
-(CCLayer*)showHelpLayer
{
self.isTouchEnabled=YES;
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:-256 swallowsTouches:YES];
...
...
[self addChild:menu];
[menu setHandlerPriority:-257];
return self;
}
and i am adding it to the main scene like that :
helpLayer *hlp=[[helpLayer alloc]init];
[hlp showHelpLayer];
[self addChild:hlp z:100];
you could toy with priorities, but it gets nasty. I only do that in very very specific, well contained circumstances. The best approach is to disable input on your "underneath scene(s)" before you push the new layer and control objects.
If you chose to play with priorities, remember that all menus default to this priority (cocos2D 2.xx) :
kCCMenuHandlerPriority = -128,
so if you play with priority, i would put the layer at -256 (swallowing touches) and setHandlerPriority to -257 for your menu. So anything that falls through your menu is caught by the layer and swallowed (ie not passed 'below').
example for priority approach. The fly-through menu is a class that extends CCNode and does this onEnter, after creating all menu objects in the init method :
- (void)onEnter {
[super onEnter];
MPLOGDEBUG(#"");
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:-256 swallowsTouches:YES];
[_backMenu setHandlerPriority:-257];
[_toggleOptionsMenu setHandlerPriority:-257];
[_dialogMenu setHandlerPriority:-257];
[_labelMenu setHandlerPriority:-257];
}

Create a left pointed UIBarButton in a UINavigation Bar Programmatically

I'm trying to create an app with a settings page just like IOS's native settings app. However I cannot find out how to create a UIBarButton that is left pointed. Basically I want a left pointed button on the top of a navigation bar, that you can set to call a function. I am using the engine cocos2d, if this helps. I am creating the entire app programmatically.
Here is my code for creating the UINavigationBar...
UINavigationBar *naviBarObj = [[[UINavigationBar alloc] initWithFrame:CGRectMake(0, 20, 320, 44)] autorelease];
[[[CCDirector sharedDirector] openGLView] addSubview:naviBarObj];
[naviBarObj release];
UINavigationItem *item = [[[UINavigationItem alloc] initWithTitle:#"Title"] autorelease];
UIBarButtonItem *back = [[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(back)] autorelease];
item.leftBarButtonItem = back;
[naviBarObj setItems:[NSArray arrayWithObjects:item, nil] animated:YES];
Although this creates a square back button.
My goal is to create something like this
I am aware that a UINavigationItem
UINavigationItem *back2 = [[[UINavigationItem alloc] initWithTitle:#"Settings"] autorelease];
with [naviBarObj setItems:[NSArray arrayWithObjects:back,item, nil] animated:YES];
will create that effect, but unfortunately I am not currently using a UINavigationController class. This is all made in a CCLayer.
Thank You!!
One way would be to use a custom back image, but that would be kind of tedious.
Another way would be like exactly what you mentioned in your last part, to create another "dummy" previous navigation item with the title set to the text you want to be on your back button, and then adding both items to the UINavigationBar.
UINavigationItem *item = [[[UINavigationItem alloc] initWithTitle:#"Title"] autorelease];
UINavigationItem *back2 = [[[UINavigationItem alloc] initWithTitle:#"Settings"] autorelease];
[naviBarObj setItems:[NSArray arrayWithObjects:back2,item, nil] animated:YES];
However I don't think you will need a UINavigationController for these to happen. In order to handle your back button event, I suppose you can try making your CCLayer a delegate of UINavigationBar, ie. UINavigationBarDelegate:
#interface MyLayer : CCLayer <UINavigationBarDelegate> {
}
then setting the delegate of your UINavigationBar to that layer:
naviBarObj.delegate = self;
and finally implement didPopItem to get notified of the event when the button is clicked:
- (void) navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item
{
[self back]; // or whatever
}
Let me know if this works.

How to enable setAliasTexParameters for CCMenuItem with Cocos2D

I'm having really hard time with my pixelated 2D game. I'm using Cocos2D framework and the menu is driving me insane. I can change the setAliasTexParameters parameter with Sprites, but not for CCMenuItemImage.
I believe it is possible with CCMenuItemSprite, but I red you can't set it straight with that either and I can't seem to even get the menu work with CCMenuItem Sprites. It works nicely with CCMenuItemImages thought.
Here's the blurry buttons:
http://cl.ly/0i1V3Y0e3u2k1t102H2a
For some unknown reason the left arrow button is sharp. I tried to change achor points, positions and paddings by 1 and 0.5 pixels but it didn't help. All the button sizes are even numbers.
This is my code for one of the MenuItems:
CCMenuItemImage *buttonMoveL = [CCMenuItemImage itemFromNormalImage:#"buttonMoveLeft.png" selectedImage:#"buttonMoveLeft2.png" block:^(id sender) {
// Do something
}
}];
And this is the Menu itself:
ActionsMenu = [CCMenu menuWithItems: buttonAttack, buttonMoveL, buttonMoveR, buttonDefend, nil];
ActionsMenu.position = ccp(240, 38);
[ActionsMenu alignItemsHorizontallyWithPadding:8];
All help is really much appreciated!
I got it working by using sprites in the menus. Here's my solution:
CCSprite *spriteDefend1 = [CCSprite spriteWithSpriteFrameName:#"buttonDefend1.png"];
CCSprite *spriteDefend2 = [CCSprite spriteWithSpriteFrameName:#"buttonDefend2.png"];
CCMenuItemImage *buttonDefend = [CCMenuItemSprite itemFromNormalSprite:spriteDefend1 selectedSprite:spriteDefend2 block:^(id sender) {
// Do something cool
}
}];

Changing Label/Sprite in CCMenu

I'm new to Cocos2D and ran into a problem when I'm trying to implement a CCMenu. I am wondering how to change the label/sprite in the CCMenu after it is added to the layer. The code below is what I've tried so far.
CGSize screenSize = [CCDirector sharedDirector].winSize;
CCLabelTTF *label1 = [CCLabelTTF labelWithString:#"HELLO!!!" fontName:#"Arial" fontSize:20];
CCLabelTTF *label2 = [CCLabelTTF labelWithString:#"BYE!!!" fontName:#"Arial" fontSize:20];
CCMenuItemLabel *labelItem1 = [CCMenuItemLabel itemWithLabel:label1];
[labelItem1 setTag:111];
CCMenu *menu = [CCMenu menuWithItems:labelItem1, nil];
[self addChild:menu];
[menu setPosition:ccp(screenSize.width/2, screenSize.height/2)];
[(CCMenuItemLabel*)[labelItem1 getChildByTag:111] setLabel:label2];
I can't figure out why the screen is still showing "HELLO!!" instead of "BYE!!!". Please help me out. I would really appreciate for your help.
hmmm the way I read this, labelItem1 is a child of menu. Try
[(CCMenuItemLabel*)[menu getChildByTag:111] setLabel:label2];

Game Center leaderboards won't show up

Okay, I've been trying to display the Game Center leaderboards in my Cocos2d iPhone game.
I have progressed and I got this piece of code:
- (void) showLeaderboard {
tempVC=[[UIViewController alloc] init];
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil)
{
leaderboardController.leaderboardDelegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview:tempVC.view];
[tempVC presentModalViewController:leaderboardController animated: YES];
}
}
When I run that in the simulator, I see it becomes portrait mode, so I know something happened. BUT nothing appears. No leaderboards come out. What is wrong?
My application is already linked with the iTunes thingy.
I am authenticated at the beginning of the game sucessfully.
I already submitted scores (with a nice thing called GameKitHelper)
Go to the AppDelegate.m and change:
[window addSubview: viewController.view];
to
window.rootViewController = viewController;
then call it
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper showLeaderboard];
This works on cocos2d 1.0.0 RC1