CCMenuItemImage is not responding when used within CCNode custom class - ios

I have created a custom class LevelScoreCard:CCNode which have some CCMenuItemImages.
Here are the interface and implementation details
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#interface LevelScoreCard : CCNode {
#private CCSprite *levelScoreBackGround;
#private CGSize winSize;
}
-(id)initForLevelNo:(int)levelNo withWiningStatus:(BOOL)won;
#end
and
#import "LevelScoreCard.h"
#import "TestLayer3.h"
#implementation LevelScoreCard
-(id)initForLevelNo:(int)levelNo withWiningStatus:(BOOL)won
{
if( (self=[super init]) ) {
winSize=[CCDirector sharedDirector].winSize;
//Adding the BackGround
levelScoreBackGround=[CCSprite spriteWithFile:#"levelScoreBackGround.png"];
self.contentSize=levelScoreBackGround.contentSize;
[self addChild:levelScoreBackGround ];
//Adding the Game Level-Wining Status
CCSprite *winingStatus;
if (won) {
winingStatus=[CCSprite spriteWithFile:#"levelCompleted.png"];
}
else{
winingStatus=[CCSprite spriteWithFile:#"levelFailed.png"];
CCSprite *skull=[CCSprite spriteWithFile:#"skull.png"];
skull.position=ccp(0,-self.contentSize.height*0.07);
[self addChild:skull];
}
winingStatus.position=ccp(0,self.contentSize.height*0.32);
[self addChild:winingStatus];
CCMenuItem *homeButton = [CCMenuItemImage itemWithNormalImage:#"home1.png"
selectedImage:#"home1.png"
block:^(id sender) {
printf("\nHome button clicked");
}];
CCMenuItem *replayButton = [CCMenuItemImage itemWithNormalImage:#"replay.png"
selectedImage:#"replay.png"
block:^(id sender) {
printf("\nReplay button clicked");
}];
CCMenuItem *nextButton;
CCMenu *menu;
NSDictionary *nextLevelInfo=[self gameInformationForLevel:levelNo+1];
//Create a menu from the button and center it on the screen
if (![[nextLevelInfo objectForKey:#"isLocked"] intValue]) {
nextButton = [CCMenuItemImage itemWithNormalImage:#"next.png"
selectedImage:#"next.png"
block:^(id sender) {
printf("\nNext button clicked");
}];
menu = [CCMenu menuWithItems:homeButton, replayButton,nextButton, nil];
[menu alignItemsHorizontallyWithPadding:60];
}
else
{
menu = [CCMenu menuWithItems:homeButton, replayButton, nil];
[menu alignItemsHorizontallyWithPadding:20];
}
menu.position = ccp(0,-self.contentSize.height*0.35);
//Add the menu as a child to this layer
[self addChild:menu];
}
return self;
}
-(NSDictionary*)gameInformationForLevel:(int)levelNo
{
//---Retrieving Information About Levels----
NSMutableDictionary *gameInfo=[[NSUserDefaults standardUserDefaults] objectForKey:#"gameInfo"];
NSString *levelKey=[NSString stringWithFormat:#"level%dInfo",levelNo];
return [[gameInfo objectForKey:levelKey] copy];
}
#end
When i am using this LevelScoreCard from simple CCLayer which is loaded directly from the IntroLayer,the blocks associated with the MenuItems are working perfectly.
But when I am using it in another CCLayer which is loaded conditionally from a second CCLayer, StartLayer with the following code,MenuItems are not responding
-(void)loadLevelAfterDelay:(ccTime)dt
{
#warning Game has 4 levels, implement game layer 2,3,4 after fixing the story
switch (levelSelected) {
case 1:
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.50 scene:[Level1 scene] ]];
break;
}
case 2:
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.50 scene:[TestLayer2 scene] ]];
break;
}
case 3:
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.50 scene:[Level1 scene] ]];
break;
}
case 4:
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.50 scene:[Level1 scene] ]];
break;
}
default:
break;
}
}

The problem was that the previous layer StartLayer:CCLayer had a SettingsMenu:CCNode which was registered to to the touchDispatcher as
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:INT_MIN+2 swallowsTouches:YES];
This was the culprit to swallow touches before they are delivered to CCMenuItemImages.So ,i learned a great lesson which says never register any CCNode type item which will swallow touch.
It's good habit not to swallow touches while registering with touchDispatcher with the following piece of code
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:INT_MIN+2 swallowsTouches:NO];

Related

Communicating between Two Layers in a Scene Cocos2d 3

I have two layers set up like so in one scene:
header file for scene:
#interface GameScene1 : CCScene {
GameLayer *gameLayer;
HUDLayer *hudLayer;
}
Main file for scene:
-(id)init {
self = [super init];
if (self != nil) {
gameLayer = [GameLayer node];
[self addChild:gameLayer];
hudLayer = [HUDLayer node];
[self addChild:hudLayer];
}
return self;
}
HUD layer header:
#interface HUDLayer : CCNode {
CCSprite *background;
CGSize screenSize;
}
-(void)updateMonstersSlayed:(NSString*)value;
HUD layer main:
#implementation HudLayer
-(id)init
{
self = [super init];
if (self)
{
CGSize viewSize = [[CCDirector sharedDirector] viewSize];
monstersSlayed = [CCLabelTTF labelWithString:#"Monsters Killed: 0" fontName:#"Arial" fontSize:15];
monstersSlayed.position = ccp(viewSize.width * 0.85, viewSize.height * 0.1 );
[self addChild:monstersSlayed];
}
return self;
}
-(void)updateMonstersSlayed:(NSString*)value
{
monstersSlayed.string = value;
}
Game Layer main
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair collisionPlayer:(CCNode *)user collisionMonster:(CCNode *)monster
{
if (holdingWeapon)
{
HudLayer *myHud = [[HudLayer alloc] init];
[myHud updateMonstersSlayed:#"Monsters Killed: 1"];
}
}
Simply trying to get it set to where I can set text from the Game Layer to show up in a Label in the Hud Layer.
How would I accomplish this in Cocos2d 3?
There are many ways you can do this. But for the sake of simplicity the easiest way you can do this is via notifications. For example in the hud add:
#implementation HudLayer
- (void)onEnter
{
[super onEnter];
NSNotificationCenter* notiCenter = [NSNotificationCenter defaultCenter];
[notiCenter addObserver:self
selector:#selector(onUpdateMonsterText:)
name:#"HudLayerUpdateMonsterTextNotification"
object:nil];
}
- (void)onExit
{
[super onExit];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)onUpdateMonsterText:(NSNotification *)notification
{
NSDictionary* userInfo = notification.userInfo;
if (userInfo)
{
NSString* text = userInfo[#"text"];
if (text)
{
[self updateMonstersSlayed:text];
}
else
{
CCLOG(#"Monster hud text param is invalid!.");
}
}
else
{
CCLOG(#"Monster hud user info invalid!");
}
}
#end
Then anywhere in your application where you want to update text you can just post the notification. Using your physics collision began example:
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair
*emphasized text*collisionPlayer:(CCNode *)user collisionMonster:(CCNode *)monster
{
if (holdingWeapon)
{
NSDictionary* userInfo = #{#"text" : #"Monsters Killed: 1"};
NSString* notiName = #"HudLayerUpdateMonsterTextNotification";
[[NSNotificationCenter defaultCenter] postNotificationName:notiName
object:self userInfo:userInfo];
}
}
Hope this helps.
You can use methods. Make a method in HUD layer class.
-(void) giveMeMyText:(NSString*)someText
{
do something with my someText
}
Don't forget to make the method visible in HUD.h -(void) giveMeMyText; Then import HUD layer class in GameScene1 #import "HUDlayer.h" and use it.
HUDLayer* myHud = [[HUDLayer alloc] init];
[myHud giveMeMyText:#"say hi!"];
You could use delegation, so your scene would implement GameLayerProtocol and the delegate of GameLayer. That way the scene would be notified of any changes the GameLayer has and act appropriately on the HudLayer.
For example:
// GameLayer class
#protocol GameLayerProtocol <NSObject>
- (void)someThingHappenedInGameLayer;
#end
#interface GameLayer : CCNode
#property (nonatomic, weak) id<GameLayerProtocol> delegate;
#end
#implementation GameLayer
- (void)someActionInGameLayer
{
[self.delegate someThingHappenedInGameLayer];
}
#end
// Scene class
#interface IntroScene : CCScene <GameLayerProtocol>
#end
#implementation IntroScene
// Implement protocol methods
- (void)someThingHappenedInGameLayer
{
//Do something with your HUDLayer here
}
#end

Push a ViewController from a Cocos2d scene

I am loading a cocos2d game inside an Storyboard. I implemented a CocosViewController that loads the cocos2d scene (IntroLayer) and IntroLayer that starts the game. I would like to go back to CocosViewController or open a new viewcontroller when the timer (countdown) is zero in the game.
I tried calling [[CCDirector sharedDirector] popScene]; when the countdown arrives to zero and with CocosViewController *cocos = [[CocosViewController alloc] init]; [cocos.navigationController dismissViewControllerAnimated:YES completion:nil];
in onExit method but the app crashes when the countdown arrives to zero, any suggestion?
My CocosViewController set up cocos2d
-(void)setupCocos2d {
CCDirector *director = [CCDirector sharedDirector];
//[[[self navigationController] navigationBar] setHidden:YES];
if([director isViewLoaded] == NO)
{
// Create the OpenGL view that Cocos2D will render to.
CCGLView *glView = [CCGLView viewWithFrame:self.view.bounds
pixelFormat:kEAGLColorFormatRGB565
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
// Assign the view to the director.
director.view = glView;
// Initialize other director settings.
[director setAnimationInterval:1.0f/60.0f];
[director enableRetinaDisplay:YES];
}
// Set the view controller as the director's delegate, so we can respond to certain events.
director.delegate = self;
// Add the director as a child view controller of this view controller.
[self addChildViewController:director];
// Add the director's OpenGL view as a subview so we can see it.
[self.view addSubview:director.view];
[self.view sendSubviewToBack:director.view];
// Finish up our view controller containment responsibilities.
[director didMoveToParentViewController:self];
// Run whatever scene we'd like to run here.
NSArray *parameters = [[NSArray alloc] initWithObjects:#"3", #"sound", #"countdown", nil];
if(director.runningScene)
[director replaceScene:[IntroLayer scene];
else
[director pushScene:[IntroLayer scene];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"cocos2d controller viewdidload");
[self setupCocos2d];
}
-(void)viewDidUnload {
NSLog(#"did unload");
[[CCDirector sharedDirector] setDelegate:nil];
[[CCDirector sharedDirector] end];
}
IntroLayer creates the scene for the game. This is my onExit method:
-(void) onExit{
NSLog(#"Introscene exit");
[super onExit];
}
And this is the game. I want to load a viewcontroller when the game finished.
-(void)update:(ccTime)dt{
if (myTime > 0) {
myTime -= (float)dt;
[timeLabel setString:[NSString stringWithFormat:#"%.2f", myTime]];
} else {
myTime = 0;
[timeLabel setString:[NSString stringWithFormat:#"0.00"]];
[[CCDirector sharedDirector] popScene];
}
if (clicks < currentClicks) {
clicks = currentClicks;
//[clicksLabel setString:[NSString stringWithFormat:#"%i", clicks]];
}
}
-(void) onExit
{
[super onExit];
[[CCDirector sharedDirector] stopAnimation];
CocosViewController *cocos = [[CocosViewController alloc] init];
[cocos.navigationController dismissViewControllerAnimated:YES completion:nil];
// [cocos.navigationController popViewControllerAnimated:YES];
//AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
//[app.navController popViewControllerAnimated:YES];
//dismissModalViewControllerAnimated:YES
NSLog(#"game exit");
}
For pop IntroLayer To ViewConrtroller As below code
[[[CCDirector sharedDirector] navigationController] popViewControllerAnimated:YES];

CCButton not working completely when pressed in Cocos2D v3 iOS

I have a gameplay scene, over which I add a CCNode as a child. My Game Over node has a replay CCButton in it.
The button is supposed to restart the game play scene. The problem is, when I press the "Restart" button, it goes through the lines but it doesn't perfrom replaceScene. Also it doesn't highlight when pressed. Here's my relevant code:
The code where I add the Game Over Node in my GamePlay Class (.m):
CCNode GameOver = [[GameOverNode alloc] init];
[self unscheduleAllSelectors];
[self stopAllActions];
[[OALSimpleAudio sharedInstance] stopBg];
[[CCDirector sharedDirector] stopAnimation];
[[CCDirector sharedDirector] pause];
[self addChild:GameOver z:5];
and here's the code for GameOver Class (.h):
#interface GameOverNode:CCNode {
CCButton *_aButton;
}
#property (nonatomic, retain) CCButton *aButton;
- (id)init;
- (void)ButtonPressed:(id)sender;
and Game Over (.m):
-(id)init {
if ( self = [super init] ){
CCSpriteFrame *replayFrame = [CCSpriteFrame frameWithImageNamed:#"Replay.png"];
_aButton = [CCButton buttonWithTitle:#"" spriteFrame:replayFrame];
_aButton.position = ccp(200,200);
[_aButton setTarget:self selector:#selector(ButtonPressed:)];
[self addChild:_aButton z:2];
}
return self;
}
- (void)ButtonPressed:(id)sender
{
NSLog(#"Button pressed");
CCTransition* t = [CCTransition transitionFadeWithDuration:0.4f];
t.outgoingSceneAnimated = YES;
t.incomingSceneAnimated = YES;
[[CCDirector sharedDirector] replaceScene:[GamePlayScene scene] withTransition:t];
}
The thing is, it prints out "Button pressed", also goes through the rest of the code of the method, but nothing happens.
I'll appreciate if you can let me know what I am doing wrong.
Thanks!
It does not work because you have paused the CCDirector. Remove the following line:
[[CCDirector sharedDirector] pause];
Alternatively if you really need that, resume the director before you attempt to replace the scene.
[[CCDirector sharedDirector] resume];
[[CCDirector sharedDirector] replaceScene:[GamePlayScene scene] withTransition:t];

Restarting game/scene from another layer

I’m having a real headache trying to diagnose this problem for quiet awhile now.
Details:
I have the following nodes:
GameLayer; the main game layer, also a semi-singleton.
HUDLayer; a simple HUD layer (for score and pause button), added to the scene along with GameLayer of course.
PauseLayer; a CCLayerColor subclass which holds a simple menu (resume, restart, and main menu).
The PauseLayer is added to the GameLayer as a child whenever the pause button is pressed.
Problem:
Restarting the game/scene works fine by: [self restartGame] from within GameLayer itself.
But invoking the same method from PauseLayer by using: [[GameLayer sharedGameLayer] restartGame] does not completely replace the GameLayer scene with a new instance; old scene is still there with no childs, same old score, etc, albeit GameLayer’s dealloc is being called (Only if no transition is used).
Code:
GameLayer
static GameLayer *sharedGameLayer;
#implementation GameLayer
- (id)init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if(self = [super initWithColor:ccc4(255, 255, 255, 255) width:[CCDirector sharedDirector].winSize.width height:[CCDirector sharedDirector].winSize.height])
{
NSLog(#"%s", __PRETTY_FUNCTION__);
sharedGameLayer = self;
.
.
}
+ (GameLayer *)sharedGameLayer {
#synchronized(self) {
if (sharedGameLayer == nil) {
sharedGameLayer = [[self alloc] init];
}
}
return sharedGameLayer;
}
- (void)pauseGame
{
NSLog(#"%s", __PRETTY_FUNCTION__);
if (![[CCDirector sharedDirector] isPaused])
{
// Disable the top menu.
self.hud.topMenu.enabled = NO;
// Pause game.
[[CCDirector sharedDirector] pause];
// Pause the background music.
[[SimpleAudioEngine sharedEngine] pauseBackgroundMusic];
// Disable touch detection.
[[CCDirector sharedDirector].touchDispatcher removeDelegate:self];
// Add the Pause Layer.
PauseLayer *pauseLayer = [[PauseLayer alloc] init];
pauseLayer.tag = 2;
pauseLayer.zOrder = 10;
[self addChild:pauseLayer z:10 tag:2];
}
}
- (void)restartGame
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[CCDirector sharedDirector].touchDispatcher removeAllDelegates];
[self stopAllActions];
[self unscheduleAllSelectors];
[self unscheduleUpdate];
[self removeAllChildrenWithCleanup:YES];
[[CCDirector sharedDirector] replaceScene:[GameLayer scene]];
//[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[GameLayer scene]]];
}
- (void)dealloc
{
NSLog(#"%s", __PRETTY_FUNCTION__);
sharedGameLayer = nil;
}
#end
PauseLayer
- (id)init
{
if (self = [super initWithColor:ccc4(0, 0, 0, 128) width:[CCDirector sharedDirector].winSize.width height:[CCDirector sharedDirector].winSize.height])
{
// Create a menu.
// Resume button.
CCLabelTTF *resumeLabel = [CCLabelTTF labelWithString:#"Resume" fontName:#"Marker Felt" fontSize:32];
resumeLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *resumeButton = [CCMenuItemLabel itemWithLabel:resumeLabel block:^(id sender) {
[[GameLayer sharedGameLayer] resumeGame];
}];
// Restart Game button.
CCLabelTTF *restartLabel = [CCLabelTTF labelWithString:#"Restart" fontName:#"Marker Felt" fontSize:32];
restartLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *restartButton = [CCMenuItemLabel itemWithLabel:restartLabel block:^(id sender) {
[[GameLayer sharedGameLayer] restartGame];
}];
// Main Menu button.
CCLabelTTF *mainMenuLabel = [CCLabelTTF labelWithString:#"Main Menu" fontName:#"Marker Felt" fontSize:32];
mainMenuLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *mainMenuButton = [CCMenuItemLabel itemWithLabel:mainMenuLabel block:^(id sender) {
[[GameLayer sharedGameLayer] gotoMainMenu];
}];
CCMenu *menu = [CCMenu menuWithItems:resumeButton, restartButton, mainMenuButton, nil];
[menu alignItemsVerticallyWithPadding:10.0];
menu.position = ccp([CCDirector sharedDirector].winSize.width / 2, [CCDirector sharedDirector].winSize.height / 2);
[self addChild:menu];
}
return self;
}
EDIT:
If I add the Pause layer (as a child to GameLayer, and always visible) in the GameLayer's init method, everything works perfectly.. which is a bit weird.
Any input is highly appreciated.
Thanks in advance!
from the line
static GameLayer *sharedGameLayer;
You needed to write this line before #implementation class line to make it isn't class member variable. and at sharedGameLayer method you should change it to
+ (GameLayer *)sharedGameLayer {
#synchronized(self) {
if (sharedGameLayer == nil) {
sharedGameLayer = [[self alloc] init];
}
}
return sharedGameLayer;
}
And, when you define game layer class you don't call init method but you should call sharedGameLayer to make game layer class be singleton.
I would not suggest using singleton pattern on CCLayers, however did you override / edit the CCScene wrapper so it doesn't call init.
For instance
+(id)scene
{
CCScene* scene = [CCScene node];
[scene addChild:[GameLayer sharedGameLayer]];
return scene;
}
Then when you call
[[CCDirector sharedDirector] replaceScene:[GameLayer scene]];
Remember to restart your game right after
[[GameLayer sharedInstance] restart];
Or you could do that in the scene wrapper method.
Hope I got your point.
Atleast this will save you from reallocating space for the game layer all the time hehe..
The culprit of the problem was calling the CCDirector's ReplaceScene: method after pausing the game using the CCDirector's Pause method. What I did was implementing my own "Pause" functionality mainly using: [self pauseSchedulerAndActions]; and also in my case: [[self.spidersBatchNode children] makeObjectsPerformSelector:#selector(pauseSchedulerAndActions)]; for all the children inside of the spriteBatchNode. Another problem arised for which I'll make another question.Thanks for all the replies.

How to replace layers?

I started to learn Objective-C and use cocos2D about 1 month ago.
I want to replace three different layers by tapping buttons.
At first, I tried to use "CCLayerMultiplex." Then, use "if sentence." But then the layers just overlap or crash when the buttons are tapped. I want the previous layer to disappear when the new layer appears, but the old layer remains with my code now.
I think using "CCLayerMultiplex" is my best option, but I can't make it work as I want it to.
Below is my code. I'm afraid that there're some poor sentences...
#interface GSLayout : CCLayer {
// button items
CCMenuItemImage *file1;
CCMenuItemImage *file1Pushed;
...
// Layer (replace)
CCLayer *layer1;
CCLayer *layer2;
CCLayer *layer3;
// replace layers
CCLayerMultiplex* mpLayer;
}
#end
#implementation GSLayout
-(id) init{
if( (self=[super init])) {
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
self.isTouchEnabled = YES;
// buttons
file1 = [CCMenuItemImage itemFromNormalImage:#"Icon-Small-50.png"
selectedImage: #"Icon-Small.png"
target:nil
selector:nil];
file1Pushed = [CCMenuItemImage itemFromNormalImage:#"Icon-Small.png"
selectedImage:#"Icon-Small-50.png"
target:nil
selector:nil];
CCMenuItemToggle *toggleFile1 = [CCMenuItemToggle itemWithTarget:self
selector:#selector(selectOne:)
items:file1,file1Pushed, nil];
toggleFile1.anchorPoint = CGPointMake(0.5f, 0.5f);
file2 = [[CCMenuItemImage itemFromNormalImage:#"Icon-Small-50.png"
selectedImage: #"Icon-Small.png"
target:nil
selector:nil]retain];
file2Pushed = [[CCMenuItemImage itemFromNormalImage:#"Icon-Small.png"
selectedImage:#"Icon-Small-50.png"
target:nil
selector:nil]retain];
CCMenuItemToggle *toggleFile2 = [CCMenuItemToggle itemWithTarget:self
selector:#selector(selectTwo:)
items:file2,file2Pushed, nil];
toggleFile2.anchorPoint = CGPointMake(0.5f, 0.5f);
...
CCMenu *toggleMenu = [CCMenu menuWithItems:toggleFile1,toggleFile2,toggleFile3, nil];
[toggleMenu alignItemsHorizontally];
toggleMenu.anchorPoint = CGPointMake(0, 1.0f);
CGSize screenSize = [[CCDirector sharedDirector] winSize];
toggleMenu.position = CGPointMake(screenSize.width/2, screenSize.height);
[self addChild:toggleMenu];
// create layers
layer1 = [GameFile1 node];
layer2 = [GameFile2 node];
layer3 = [GameFile3 node];
mpLayer = [CCLayerMultiplex layerWithLayers:layer1,layer2,layer3, nil];
}
return self;
}
- (void) selectOne: (CCMenuItem*) menuItem
{
NSLog(#"The first menu was called");
if([layer1 isRunning])
{
nil;
NSLog(#"The layer1 is running");
} else if([layer2 isRunning]) {
[mpLayer switchTo:0];
NSLog(#"The layer2 was replaced");
}else if([layer3 isRunning]) {
[mpLayer switchTo:0];
NSLog(#"The layer3 was replaced");
} else{
[self addChild:layer1];
NSLog(#"The layer1 was called");
}
}
- (void) selectTwo: (CCMenuItem*) menuItem
{
NSLog(#"The second menu was called");
if([layer2 isRunning])
{
nil;
NSLog(#"The layer2 is running");
} else if([layer1 isRunning]) {
[mpLayer switchTo:1];
NSLog(#"The layer1 was replaced");
} else if([layer3 isRunning]) {
[mpLayer switchTo:1];
NSLog(#"The layer3 was replaced");
}else{
[self addChild:layer2];
NSLog(#"The layer2 was called");
}
}
- (void) selectThree: (CCMenuItem*) menuItem
{
NSLog(#"The third menu was called");
...
}
Please give me some advice!
Thank you in advance!
I'll add some codes.
#interface GameFile1 : CCLayer {
CCSprite* sprite;
}
#implementation GameFile1
-(id) init{
if( (self=[super init])) {
CGSize screenSize = [[CCDirector sharedDirector] winSize];
CCMenuItemImage *soundItem1 = [CCMenuItemImage itemFromNormalImage:#"button1.png"
selectedImage: #"Icon.png"
target:self
selector:#selector(doSomethingOne:)];
CCMenuItemImage *soundItem2 = [CCMenuItemImage itemFromNormalImage:#"button2.png"
selectedImage: #"Icon.png"
target:self
selector:#selector(doSomethingTwo:)];
...
CCMenu * myMenu = [CCMenu menuWithItems:soundItem1, soundItem2,soundItem3,soundItem4, soundItem5,soundItem6,soundItem7, soundItem8,soundItem9,soundItem10,soundItem11,soundItem12, nil];
[myMenu alignItemsInRows:[NSNumber numberWithInt:4],[NSNumber numberWithInt:4],[NSNumber numberWithInt:4] ,nil];
myMenu.position = CGPointMake(370, 120);
[self addChild:myMenu];
sprite = [CCSprite spriteWithFile:#"o0400026611355530621.jpg"];
sprite.scale = 0.5f;
sprite.position = CGPointMake(screenSize.width/2, screenSize.height/2);
sprite.anchorPoint = CGPointMake(1.0f, 0);
[self addChild:sprite];
- (void) doSomethingOne: (CCMenuItem *) menuItem
{
NSLog(#"The first menu was called");
[[SimpleAudioEngine sharedEngine] playEffect:#"one.wav"];
[sprite setTexture:[[CCTextureCache sharedTextureCache] addImage: #"one.jpg"]];
}
- (void) doSomethingTwo: (CCMenuItem *) menuItem
{
NSLog(#"The second menu was called");
[[SimpleAudioEngine sharedEngine] playEffect:#"two.wav"];
[sprite setTexture:[[CCTextureCache sharedTextureCache] addImage: #"one.jpg"]];
}
...
#end
Since you have already loaded the textures for all three layers, you might as well have all three sitting in separate CCLayers where two are hidden at any given state using a method similar to:
- (void) setLayer:(uint)show {
layerOne.visible = (show == 0);
layerTwo.visible = (show == 1);
layerThree.visible = (show == 2);
}

Resources