Braydon Batungbacal
Braydon Batungbacal

Reputation: 1038

Cocos2d Game crashing when replacing scene (Code Included)

so something is going haywire with my Cocos2d Game. I recently added in some code that would allow me to have a dialog message at the beginning of certain levels in my game. And whenever I go to restart a level (Which replaces the scene) of a level that has the dialog cclayer added to the current scene, I get a BAD ACCESS error through the iPhone simulator, and then if I run it on my iPhone 4S I'm getting a SIGARBT error that says

"* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'child already added. It can't be added again'"

This is my first cocos2d game I'm making. I've toyed a lot with cocos2d and have what I believe is a basic understanding. I have a lot of programming experience with other languages, but I only started learning objective-c about 3 months ago.

Here is my code.

GameDialog.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "GameData.h"

@interface GameDialogLayer : CCLayer {
    NSString *dialogText;
}

@property (nonatomic, retain) NSString *dialogText;

+(CCScene *) scene;
-(void) addDialogWithText: (NSString *)text;

@end

GameDialog.m

#import "GameDialogLayer.h"


@implementation GameDialogLayer

@synthesize dialogText;

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];
    GameDialogLayer *layer = [GameDialogLayer node];
    [scene addChild: layer];
    return scene;
}

-(id) init
{
    if( (self=[super init]) ) {
        // init the bg overlay
        CCLayerColor *backgroundLayer = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 175)];
        [self addChild:backgroundLayer z:0];

        // init the dialog box
        CCSprite *dialogBox = [CCSprite spriteWithFile:@"dialog.png"];
        dialogBox.position = ccp([[CCDirector sharedDirector] winSize].width / 2, [[CCDirector sharedDirector] winSize].height / 2);
        [self addChild:dialogBox];

        // init the dialog menu
        CCMenuItemImage *dialogOkay = [CCMenuItemImage itemWithNormalImage:@"dialogOkayButton.png" selectedImage:@"dialogOkayButtonPressed.png" target:self selector:@selector(okayButton)];

        CCMenu *dialogMenu = [CCMenu menuWithItems:dialogOkay, nil];
        dialogMenu.position = ccp(dialogMenu.position.x, dialogMenu.position.y - 118);
        [self addChild:dialogMenu];
    }

    return self;
}

-(void) okayButton
{
    [GameData sharedGameData].isPaused = 0;
    [[self parent] schedule:@selector(startCountdown:) interval:1];
    [[self parent] removeChild:self cleanup:YES];
}

-(void) addDialogWithText: (NSString *)text
{
    CCLabelTTF *dialogTextLabel = [CCLabelTTF labelWithString:text dimensions:CGSizeMake(180, 250) hAlignment:kCCTextAlignmentLeft fontName:@"MarkerFelt-Thin" fontSize:20];
    dialogTextLabel.color = ccBLACK;
    dialogTextLabel.position = ccp([[CCDirector sharedDirector] winSize].width / 2, [[CCDirector sharedDirector] winSize].height / 2);
    [self addChild:dialogTextLabel];
}

- (void) dealloc
{
    [super dealloc];
}

@end

And then the dialog is being added to my dialog property in my levelData class that is istantiated for each level and holds the properties of the level.

Here is the property holding it

@property (nonatomic, retain) GameDialogLayer *dialog;

And here is how I'm adding the dialog to the levelData dialog property

-(void) addDialog: (NSString *)dialogText
{
    dialog = [GameDialogLayer node];
    [dialog addDialogWithText:dialogText];
}

Upvotes: 0

Views: 545

Answers (1)

Ben Trengrove
Ben Trengrove

Reputation: 8729

You are adding a node to the scene twice somehow, I had a look at your code and couldn't spot it but they are easy to find. Just add a breakpoint for all Objective C exceptions. The debugger will stop on the line causing the problem.

See here for how to add the breakpoint. You can change "Exception: All" to "Exception: Objective C" to avoid exceptions from CocosDenhesion if you are using it.

Upvotes: 1

Related Questions