Cocos2d - CCMenu with multiple buttons calls wrong selector on first load - iphone

Here's an interesting dilemma. I have two CCMenus being loaded on a page, each with two CCMenuItemImages as buttons. All four buttons call the same function, which decides what to do using a switch statement that goes off the caller's tag value.
The four buttons are start, tutorial, options, and credits. I have them split into two menus so that I can horizontally and vertically align them in a faux grid. This layer is the main menu layer, so it is the first thing to load after the game starts.
The problem is that when the game first loads, pressing any button will call the "options" button. Not just the function, pressing any button on the menu activates the options button's selected state. If I press "start," for instance, the start button's selected state (a glow around the image) doesn't work–the options button glows instead.
Once I get into the options menu, and then back out of it, the main menu works as expected, with each button activating its requisite function.
I should note that I've also run a clean, and removed the app from both the simulator and my iPhone and rebuilt it.
Here's my .h:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Constants.h"
#import "GameManager.h"
#interface MainMenuLayer : CCLayer {
CCMenu *mainMenuTop;
CCMenu *mainMenuBottom;
}
#end
And this is my .m:
#import "MainMenuLayer.h"
// Private methods
#interface MainMenuLayer()
- (void)displayMainMenu;
#end
#implementation MainMenuLayer
- (void)playScene:(CCMenuItemFont*) itemPassedIn {
if ([itemPassedIn tag] == 1) {
CCLOG(#"Tag 1 found, Scene 1");
[[GameManager sharedGameManager] runSceneWithID:kGameplayScene];
} else if ([itemPassedIn tag] == 2) {
CCLOG(#"Tag was: %d", [itemPassedIn tag]);
CCLOG(#"Placeholder for next chapters");
} else if ([itemPassedIn tag] == 3) {
CCLOG(#"Tag 3, Options");
[[GameManager sharedGameManager] runSceneWithID:kOptionsScene];
} else if ([itemPassedIn tag] == 4) {
CCLOG(#"Tag 4, Credits");
[[GameManager sharedGameManager] runSceneWithID:kCreditsScene];
}
}
- (void)displayMainMenu {
CGSize winSize = [CCDirector sharedDirector].winSize;
// Main Menu Top Layer Buttons
CCMenuItemImage *playGameButton = [CCMenuItemImage itemFromNormalImage:#"button-start-up.png" selectedImage:#"button-start-down.png" disabledImage:nil target:self selector:#selector(playScene:)];
[playGameButton setTag:1];
CCMenuItemImage *tutorialButton = [CCMenuItemImage itemFromNormalImage:#"button-tutorial-up.png" selectedImage:#"button-tutorial-down.png" disabledImage:nil target:self selector:#selector(playScene:)];
[tutorialButton setTag:2];
// Main Menu Bottom Layer Buttons
CCMenuItemImage *optionsButton = [CCMenuItemImage itemFromNormalImage:#"button-options-up.png" selectedImage:#"button-options-down.png" disabledImage:nil target:self selector:#selector(playScene:)];
[optionsButton setTag:3];
CCMenuItemImage *creditsButton = [CCMenuItemImage itemFromNormalImage:#"button-credits-up.png" selectedImage:#"button-credits-down.png" disabledImage:nil target:self selector:#selector(playScene:)];
[creditsButton setTag:4];
mainMenuTop = [CCMenu menuWithItems:playGameButton,tutorialButton,nil];
mainMenuBottom = [CCMenu menuWithItems:optionsButton,creditsButton,nil];
[mainMenuTop alignItemsHorizontallyWithPadding: 10.0f];
[mainMenuTop setPosition: ccp(winSize.width/2, -500)];
[mainMenuBottom alignItemsHorizontallyWithPadding:10.0f];
[mainMenuBottom setPosition:ccp(winSize.width/2, -600)];
id moveActionTop = [CCMoveTo actionWithDuration:0.5f position:ccp(winSize.width/2, 150)];
id moveEffectTop = [CCEaseIn actionWithAction:moveActionTop rate:1.0f];
[mainMenuTop runAction:moveEffectTop];
[self addChild:mainMenuTop z:2 tag:kMainMenuTagValue];
id moveActionBottom = [CCMoveTo actionWithDuration:0.5f position:ccp(winSize.width/2, 75)];
id moveEffectBottom = [CCEaseIn actionWithAction:moveActionBottom rate:1.0f];
[mainMenuBottom runAction:moveEffectBottom];
[self addChild:mainMenuBottom z:3 tag:kMainMenuBottomTagValue];
}
-(id)init {
self = [super init];
if (self != nil) {
[self displayMainMenu];
}
return self;
}
#end

I ended up just positioning things manually. I tried to use the method linked by LearnCocos2D, but I couldn't determine how to make it work properly; the items didn't end up in a proper grid.

Related

UIAlertView Rendering Error

I have been working on an app for a couple of months now, but have finally run into an issue that I can't solve myself, and can't find anything on the internet to help.
I am using several normal UIAlertViews, in my app. Some have 2 buttons, some have 3 buttons, and a couple have 2 buttons and a text field. However all have the same issue. When you call [someAlertView show]; the alert view appears as normal, but then suddenly its graphics context seems to get corrupted as you can see from the screenshot.
This happens on both iPhone and iPad simulators (both 5.0 and 5.1), and happens on an iPad and iPhone4S device as well.
The image showing through is whatever happens to be behind the alertView.
The Alert still works, I can click the buttons, type in the text field, then when it dismisses the delegate methods are called correctly and everything goes back to normal. When the alertView appears again, the same thing happens.
The view behind the alert is a custom UIScrollView subclass with a content size of approximately 4000 pixels by 1000 with a UIImage as the background. The png file is mostly transparent, so is only about 80kB in memory size, and the phone is having no issues rendering it - the scroll view is still fully responsive and not slow.
It also has a CADisplayLink timer attached to it as part of the subclass. I have tried disabling this just before the alertView is shown, but it makes no difference so I am doubtful that is the issue.
This app is a partial rewrite of one I made for a university project, and that one could display UIAlertViews over the top of a scrollView of the same size and subclass without issue. The difference between this app and that one is that in my old app, I had subclassed UIAlertView to add extra things such as a pickerView, however I decided that I didn't like the way it looked so moved everything out of the alert and am just sticking with a standard UIAlertView.
This is how the alertView in the screenshot is called:
- (IBAction)loadSimulation:(id)sender {
importAlert = [[UIAlertView alloc] initWithTitle:#"Load Simulation" message:#"Enter Filename:" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Load", nil];
[importAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[importAlert showPausingSimulation:self.simulationView]; //Calling [importAlert show]; makes no difference.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self hideOrganiser]; //Not an issue as the problem occurs on iPad as well.
}
}
With this being the categorised AlertView to add the ability to stop the scrollViews CADisplay link.
#interface UIAlertView(pauseDisplayLink)
- (void)showPausingSimulation:(UILogicSimulatorView*)simulationView;
#end
#implementation UIAlertView(pauseDisplayLink)
- (void)showPausingSimulation:(UILogicSimulatorView *)simulationView {
[simulationView stopRunning];
[simulationView removeDisplayLink]; //displayLink needs to be removed from the run loop, otherwise it will keep going in the background and get corrupted.
[self show];
}
I get no memory warnings when this happens, so I am doubtful it is due to lack of resources.
Has anyone come across an issue like this before? If you need further information I can try to provide it, but I am limited in what code I can post. Any help would be appreciated, I've been trying to solve this for two weeks and can't figure it out.
Edit:
It appears that it is not the AlertView at all (or rather it is not just the alertView), as the problem goes away when I remove the scroll view behind it, so there must be some issue between the two. This is the code for my UIScrollView subclass:
.h file:
#import
#import
#class ECSimulatorController;
#interface UILogicSimulatorView : UIScrollView {
CADisplayLink *displayLink;
NSInteger _updateRate;
ECSimulatorController* _hostName;
}
#property (nonatomic) NSInteger updateRate;
#property (nonatomic, strong) ECSimulatorController* hostName;
- (void) removeDisplayLink;
- (void) reAddDisplayLink;
- (void) displayUpdated:(CADisplayLink*)timer;
- (void) startRunning;
- (void) stopRunning;
- (void) refreshRate:(NSInteger)rate;
- (void) setHost:(id)host;
- (void)setMinimumNumberOfTouches:(NSInteger)touches;
- (void)setMaximumNumberOfTouches:(NSInteger)touches;
#end
.m file:
#import "UILogicSimulatorView.h"
#import "ECSimulatorController.h"
#import <QuartzCore/QuartzCore.h>
#implementation UILogicSimulatorView
#synthesize updateRate = _updateRate;
#synthesize hostName = _hostName;
- (void)reAddDisplayLink {
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //allows the display link to be re-added to the run loop after having been removed.
}
- (void)removeDisplayLink {
[displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; //allows the display link to be removed from the Run loop without deleting it. Removing it is essential to prevent corruption between the games and the simulator as both use CADisplay link, and only one can be in the run loop at a given moment.
}
- (void)startRunning {
[self refreshRate:self.updateRate];
[displayLink setPaused:NO];
}
- (void)refreshRate:(NSInteger)rate {
if (rate > 59) {
rate = 59; //prevent the rate from being set too an undefined value.
}
NSInteger frameInterval = 60 - rate; //rate is the number of frames to skip. There are 60FPS, so this converts to frame interval.
[displayLink setFrameInterval:frameInterval];
}
- (void)stopRunning {
[displayLink setPaused:YES];
}
- (void)displayUpdated:(CADisplayLink*)timer {
//call the function that the snakeController host needs to update
[self.hostName updateStates];
}
- (void)setHost:(ECSimulatorController*)host;
{
self.hostName = host; //Host allows the CADisplay link to call a selector in the object which created this one.
}
- (id)initWithFrame:(CGRect)frame
{
//Locates the UIScrollView's gesture recogniser
if(self = [super initWithFrame:frame])
{
[self setMinimumNumberOfTouches:2];
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(displayUpdated:)]; //CADisplayLink will update the logic gate states.
self.updateRate = 1;
[displayLink setPaused:YES];
}
return self;
}
- (void)setMinimumNumberOfTouches:(NSInteger)touches{
for (UIGestureRecognizer *gestureRecognizer in [self gestureRecognizers])
{
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
//Changes the minimum number of touches to 'touches'. This allows the UIPanGestureRecogniser in the object which created this one to work with one finger.
[(UIPanGestureRecognizer*)gestureRecognizer setMinimumNumberOfTouches:touches];
}
}
}
- (void)setMaximumNumberOfTouches:(NSInteger)touches{
for (UIGestureRecognizer *gestureRecognizer in [self gestureRecognizers])
{
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
//Changes the maximum number of touches to 'touches'. This allows the UIPanGestureRecogniser in the object which created this one to work with one finger.
[(UIPanGestureRecognizer*)gestureRecognizer setMaximumNumberOfTouches:touches];
}
}
}
#end
Well, I have managed to come up a solution to this. Really it is probably just masking the issue rather than finding the route cause, but at this point I will take it.
First some code:
#interface UIView (ViewCapture)
- (UIImage*)captureView;
- (UIImage*)captureViewInRect:(CGRect)rect;
#end
#implementation UIView (ViewCapture)
- (UIImage*)captureView {
return [self captureViewInRect:self.frame];
}
- (UIImage*)captureViewInRect:(CGRect)rect
{
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot;
}
#end
- (void)showPausingSimulation:(UILogicSimulatorView *)simulationView {
[simulationView stopRunning];
UIView* superView = simulationView.superview;
CGPoint oldOffset = simulationView.contentOffset;
for (UIView* subview in simulationView.subviews) {
//offset subviews so they appear when content offset is (0,0)
CGRect frame = subview.frame;
frame.origin.x -= oldOffset.x;
frame.origin.y -= oldOffset.y;
subview.frame = frame;
}
simulationView.contentOffset = CGPointZero; //set the offset to (0,0)
UIImage* image = [simulationView captureView]; //Capture the frame of the scrollview
simulationView.contentOffset = oldOffset; //restore the old offset
for (UIView* subview in simulationView.subviews) {
//Restore the original positions of the subviews
CGRect frame = subview.frame;
frame.origin.x += oldOffset.x;
frame.origin.y += oldOffset.y;
subview.frame = frame;
}
[simulationView setHidden:YES];
UIImageView* imageView = [[UIImageView alloc] initWithFrame:simulationView.frame];
[imageView setImage:image];
[imageView setTag:999];
[superView addSubview:imageView];
[imageView setHidden:NO];
superView = nil;
imageView = nil;
image = nil;
[self show];
}
- (void)dismissUnpausingSimulation:(UILogicSimulatorView *)simulationView {
UIView* superView = simulationView.superview;
UIImageView* imageView = (UIImageView*)[superView viewWithTag:999];
[imageView removeFromSuperview];
imageView = nil;
superView = nil;
[simulationView setHidden:NO];
[simulationView startRunning];
}
Then modifying the dismiss delegate method in my class to have this line:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[alertView dismissUnpausingSimulation:self.simulationView];
...
When the alert view is called, but before it is shown, I need to hide the simulator to prevent it corrupting the alert. However just hiding it is ugly as then all is visible behind is a empty view.
To fix this, I first make a UIImage from the simulator views graphics context. I then create a UIImageView with the same frame as the simulator and set the UIImage as its image.
I then hide the simulator view (curing the alert issue), and add my new UIImageView to the simulators superview. I also set the tag of the image view so I can find it later.
When the alert dismisses, the image view is then recovered based on its tag, and removed from its superview. The simulator is then unhidden.
The result is that the rendering issue is gone.
I know its too late for an answer to this question. Lately I had experianced this very same issue.
My Case:
Added couple of custom UIViews with background images and some controlls to the scroll view with shadow effect. I had also set the shadowOffset.
The Solution:
After some step by step analysis, I found out that setting the setShadowOpacity caused The rendering problem for me. When i commented that line of code, it cured the UIAlertView back to normal appearance.
More:
To make sure, I created a new project mimicing the original ui with shadowOpacity. But it didnt caused the rendering problem as i expected. So I am not sure about the root cause. For me it was setShadowOpacity.

how do I add a menu to an already-made game in cocos2d and box2d for iphone?

I have an existing game that I want to have a title screen with a button "play" to the app that loads the game.
EDIT: The interface was made in Level Helper
Here's how you can implement a menu that changes scenes with a transition. In your HelloWorldLayer.m file, add this:
-(id) init
{
if( (self=[super init])) {
CCMenuItemImage *menuImage = [CCMenuItemImage itemFromNormalImage:#"yourimage.png" selectedImage:#"Icon.png" target:self selector:#selector(changeScene:)];
CCMenu *menu;
menu = [CCMenu menuWithItems:menuImage, nil];
[self addChild:menu];
}
return self;
}
-(void) changeScene:(id)sender
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:1 scene:[Scene1 node]]];
}
This creates a menu item image assigned to a selector, adds it to a menu, and then on click, transitions to a new scene, which I will show you how to do now. Create a new class called Scene1, and just to show that the transition worked, we will add a sprite in this new scene. In your init method:
-(id) init
{
if( (self=[super init])) {
sprite = [CCSprite spriteWithFile:#"yourimage.png"];
sprite.position = ccp(100,200);
[self addChild:sprite];
}
return self;
}
If you see this new sprite on the screen, it means that everything worked.
I'll assume by saying u have an existing game, that u have the source code of the game.
All u need is to make a new CCLayer with a CCMenu (containing the CCMenuButton u want) that all it does is load the CCLayer that loads as u start the game, and make ur CCLayer the one that gets loaded as u start the app.
create a menu using the following code:
// Intalize your menu item
CCMenuItem *menuItem = [CCMenuItemFont itemFromString:#"This is what you want your item to say" target:self selector:#selector(selectorToHandleYourSelection)];
// Define where you want your item to be
menuItem.position = ccp(100,100);
// Intalize a menu for your menu item
CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
// Add the 'menu' as a child to your layer
[self addChild:menu];
// If the item position isn't defined then you can align the items horizontally
[menu alignItemsHorizontally];

Cocos2d iPhone Game Remove menu from scene

I have written a few games using Cocos2d iPhone. In all of my previous games I would change scenes when I setup a CCMenu and then leave that scene when I was finished. In my current project, I need the menu to exist in my current scene and be able to open and then close the menu many times. For some reason, I can't seem to understand, removeChild will not remove the menu. I have seen several examples online that show using removeChild, but it does not work for me. Below is my menu code, when the Start/CreateNewAccount button is pressed I want the current menu to be removed from the scene completely.
This is in my init method.
CCMenuItemImage *Start = [CCMenuItemImage itemFromNormalImage:#"MakeLemonade.png" selectedImage:#"MakeLemonadePressed.png"
target:self
selector:#selector(CreateNewAccount:)];
CCMenuItemImage *About = [CCMenuItemImage itemFromNormalImage:#"About.png" selectedImage:#"AboutPressed.png"
target:self
selector:#selector(About:)];
Start.position = ccp(-175, -90);
About.position = ccp(175, -90);
CCMenu *MainMenu = [CCMenu menuWithItems: Start, About, nil];
[Start runAction:[CCFadeIn actionWithDuration:1.0]];
[About runAction:[CCFadeIn actionWithDuration:1.0]];
[self addChild:MainMenu z:6];
}
return self;
}
-(void) BeginMenuLayer {
//this is not working
[self removeChild:MainMenu cleanup:YES];
}
In your init method you've declared MainMenu as a local variable. You're not setting it as a property, so you don't have a reference when you go to remove it later.
1) Make sure you have a property declared for it like this:
#property (nonatomic, retain) CCMenu *MainMenu;
2) Synthesize it at the top of your implementation:
#synthesize MainMenu;
3) Make sure you release it in your dealloc:
-(void)dealloc {
self.MainMenu = nil;
[super dealloc];
}
4) When you construct it, assign it to your property rather than a local variable:
self.MainMenu = [CCMenu menuWithItems: Start, About, nil];
Now you have a retained reference to the object, which you can pass later to removeChild:cleanup:.

Problem With CCMenuItem

Iam trying to create simple menu according to the book CCMenuItem . here is my MenuView.m code
bot nothing happens just a black screen appears ! without any menu !
iam working with COCOS2D 0.99.5
//
// MenuView.m
// Sence
#import "MenuView.h"
#import "HelloWorldScene.h"
#implementation MenuView
// in dastor hatman bayad dar menu badi neveshte shavad ke be onvane ye view shenasande shavad
+(id) scene
{
CCScene* scene = [CCScene node];
CCLayer* layer = [MenuView node];
[scene addChild:layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
CCLOG(#"init %#", self);
// wait a short moment before creating the menu so we can see it scroll in
[self schedule:#selector(createMenu:) interval:2];
}
return self;
}
- (void) menuItem1Touched {
NSLog(#"test");
}
- (void) createMenu:(ccTime) delta {
[self unschedule:_cmd];
CGSize size = [[CCDirector sharedDirector] winSize];
// set CCMenuItemFont default properties
[CCMenuItemFont setFontName:#"Helvetica-BoldOblique"];
[CCMenuItemFont setFontSize:40];
// create a few labels with text and selector
CCMenuItemFont* item1 = [CCMenuItemFont itemFromString:#"Go Back!" target:self selector:#selector(menuItem1Touched:)];
// create the menu using the items
CCMenu* menu = [CCMenu menuWithItems:item1, nil];
menu.position = CGPointMake(-(size.width / 2), size.height / 2);
menu.tag = 100;
[self addChild:menu];
// calling one of the align methods is important, otherwise all labels will occupy the same location
[menu alignItemsVerticallyWithPadding:40];
}
#end
Your this line:
CCMenuItemFont* item1 = [CCMenuItemFont itemFromString:#"Go Back!" target:self selector:#selector(menuItem1Touched:)];
should be
CCMenuItemFont* item1 = [CCMenuItemFont itemFromString:#"Go Back!" target:self selector:#selector(menuItem1Touched)];
Change from menuItem1Touched: to menuItem1Touched.. Remove the :
Tested and works..

how to change the lock images to unlock images in cocos2d

am having game with 10 levels. i want to change the second level lock image to unlock when first level is completed.
am using 20 images ( 10 locked and 10 unlocked).
am using cc menus to display the number images.
for example(code):-
CCMenuItemImage *startButton12 = [CCMenuItemImage itemFromNormalImage:#"ten_new-lock.png"
selectedImage:#"ten_new-lock.png" target:self
selector:#selector(ten:)];
menu1 = [CCMenu menuWithItems: startButton3,startButton4,startButton5,startButton6,startButton7,startButton8,startButton9,startButton10,startButton11,startButton12, nil];
menu1.position = ccp(240,30);
[menu1 alignItemsHorizontally];
[menuLayer1 addChild: menu1];
am using below code for remember the level completed.
int lastLevelCompleted= [[NSUserDefaults standardUserDefaults] integerForKey:#"levelCompleted"];
if(currentLevel >lastLevelCompleted){
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:currentLevel forKey:#"levelCompleted"];
**now, how to change the lock to unlock images.
( if am doing here wrong)there is other way to solve means provide that. i have to implement that one.**
You could set a disabledImage when you create each CCMenuItemImage:
// create items by delclaring also a "disabled" image
CCMenuItemImage *menuItem = [CCMenuItemImage itemFromNormalImage:normalImage
selectedImage:selectedImage
disabledImage:disabledImage
target:self
selector:#selector(callbackMethod)];
Then just switch the state of the button as requested:
// then just use setIsEnabled to switch the state
[menuItem setIsEnabled:NO];
Cocos swaps the images for you.
I have the same idea in one of my games. I solved it with separate lock and done icons that I have positioned on top of each menu item that represents a level.
Just create your menu items normally. Don't try to represent locked or done states with the menu item's icon. Instead create a smaller locked and done icons that you will instantiate as sprites and position on top of each menu item.
Here is the relevant part of my menu layer's init method (I'm using a sprite atlas to store all my images):
// I save the state of each level as a character in a NSMutableString:
self.completedState = 0x0043; // "C" (Completed)
self.openState = 0x004f; // "O"
self.lockedState = 0x004c; // "L"
self.dungeonAvailabilityState = #"COLLLLLLLLLLLLLLLL"; // in reality I get this string from a global object
// calc the position for the dungeon icon at row, column
x = (column*56)+148;
y = 244-(row*56);
// get the dungeon state
stateIndex = (row*columns)+column;
dungeonState = [self.dungeonAvailabilityState characterAtIndex:stateIndex];
// calc the position of the badges using offset from the menu item's icon
lockedX = x - DungeonsScreen_BadgeXoffset;
lockedY = y - DungeonsScreen_BadgeYoffset;
doneX = x - DungeonsScreen_BadgeXoffset;
doneY = y + DungeonsScreen_BadgeYoffset;
if (dungeonState == self.lockedState) {
// add the lock icon
[super badgeIconFromFrame:#"icon_lock.png" xPos:lockedX yPos:lockedY spriteTag:t++];
}
and my helper method badgeIconFromFrame looks like this:
- (void) badgeIconFromFrame:(NSString*)spriteName xPos:(float)x yPos:(float)y spriteTag:(int)t {
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
CCSprite* badgeSprite = [CCSprite spriteWithSpriteFrameName:spriteName];
badgeSprite.position = CGPointMake(x, y);
[self addChild:badgeSprite z:zIndexDecoration tag:t];
}
What about (void) - setIsEnabled: method of CCMenuItem ?
Not sure if it works:
if(unlock){
[menuLayer1 removeChild: menu1 cleanup:YES];
CCMenuItemImage *startButton12 = [CCMenuItemImage itemFromNormalImage:#"ten_new-unlock.png"
selectedImage:#"ten_new-unlock.png" target:self
selector:#selector(ten:)];
menu1 = [CCMenu menuWithItems: startButton3,startButton4,startButton5,startButton6,startButton7,startButton8,startButton9,startButton10,startButton11,startButton12, nil];
menu1.position = ccp(240,30);
[menu1 alignItemsHorizontally];
[menuLayer1 addChild: menu1];
}
else
{
CCMenuItemImage *startButton12 = [CCMenuItemImage itemFromNormalImage:#"ten_new-lock.png"
selectedImage:#"ten_new-lock.png" target:self
selector:#selector(ten:)];
menu1 = [CCMenu menuWithItems: startButton3,startButton4,startButton5,startButton6,startButton7,startButton8,startButton9,startButton10,startButton11,startButton12, nil];
menu1.position = ccp(240,30);
[menu1 alignItemsHorizontally];
[menuLayer1 addChild: menu1];
}
did u try using db (sqlite) to store the value of locked or unlocked.
It will definitely work.
But it is a big process.
Just use [menuItem setNormalImage:lockedButton];
LockedButton being another CCMenuItemImage with a new file.