Reputation: 1038
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
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