# Crash when using Cocos2d

Sorry about the poor question title, it's just that this seems to big for a title. So here's the dirt:

I am making a game (obviously) and I want the enemies to shoot (not necessarily at the player). I want the shoot method to be in the Enemies file, so as not to clutter up my HelloWorldLayer.m file even more. Here's what I'm using right now:

HelloWorldLayer.m

-(void)addEnemy:(BigAndStrongEnemy *)enemy {
enemy = nil;
if((arc4random() % 4) == 3) {
enemy = [BigAndStrongEnemy enemy];
} else {
enemy = [SmallAndFastEnemy enemy];
}

if(buffDude.position.y > character.position.y || buffDude.position.y < (character.position.y + 10)) {

}

int rand = arc4random() % 320;

if((arc4random() % 2 == 1)) {
[enemy setPosition:ccp(0,rand)];
}else{
[enemy setPosition:ccp(480,rand)];
}
[self animateEnemy:enemy];
}

-(void)animateEnemy:(BigAndStrongEnemy *)enemy2 {
float randX = arc4random() % 480;
float randY = arc4random() % 320;
int rand = arc4random() % 320;

CGPoint moveToPoint = CGPointMake(randX, (randY - rand));

action = [CCSequence actions:
[CCMoveBy actionWithDuration:1 position:ccpMult(ccpNormalize(ccpSub(moveToPoint, enemy2.position)), 75)],
[CCMoveBy actionWithDuration:3 position:ccp(buffDude.position.x,buffDude.position.y)],
nil];

CCCallFuncO *a = [CCCallFuncO actionWithTarget:self selector:(@selector(shoot:)) object:enemy2];
CCSequence *s = [CCSequence actions:action,a, nil];

CCRepeatForever *repeat = [CCRepeatForever actionWithAction:s];

[enemy2 runAction:repeat];
}


And here's the Shoot info from the Enemies class:

Enemies.m:

    -(void)shoot:(id)sender {
self = (BigAndStrongEnemy *)sender;
[self shoot];
}

-(void)spriteMoveFinished:(id)sender {
CCSprite *b = (CCSprite *)sender;
[self removeChild:b cleanup:YES];
}

-(void)shoot {
self = [CCSprite spriteWithFile:@"bigAndStrongEnemy.gif"];
CCSprite *b = [CCSprite spriteWithFile:@"bullet.gif"];
b.position = ccp(self.position.x,self.position.y);
b.tag = 2;

CGSize winSize = [[CCDirector sharedDirector] winSize];

CGPoint point = CGPointMake((winSize.width - (winSize.width - self.position.x)),0);

[b runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:0.5 position:point],
[CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)],
nil]];
}


Every time the 3 seconds goes by, the app crashes, and goes to the breakpoint in the CCCallFuncO file. I haven't touched it, is the thing. I am completely confused. Any help is greatly appreciated.

• -1 use your debugger – Maik Semder Jul 5 '11 at 7:08

Use the XCode debugger and do a stack track to see the last line of your code where the crash happened. That should give you a clue on what is causing the error

• I've never used the xcode debugger. How do I? – Duncan May 10 '11 at 22:44
• @ipodfreak0313 why dont you check the xcode help or google tutorial xcode debugger. This is not the right place to teach basic programming skills – Maik Semder Jul 5 '11 at 7:05
• I wrote an Xcode 4 Debugging Crash-Course article: learn-cocos2d.com/2011/10/xcode-4-debugging-crashcourse – LearnCocos2D Oct 12 '11 at 10:04

I had a similar problem with "CCCallFunc". It turned out I needed to be using "CCCallFuncN" instead, confusing because they are so similarly named. I would try replacing the line of code it's tripping up on with

CCCallFuncN *a = [CCCallFuncN actionWithTarget:self selector:(@selector(shoot:)) object:enemy2];


The enemy class has

[self addChild]


and

[self removeChild]


that I think make more sense in the Layer class, unless the Enemy class is based on Layer.

Did you try moving the enemy code to the HelloWorldLayer? I know this is not where you want it to be, but it may be simpler to get it to work, then change it from there.

Bingo. The problem exists in CCCallFunc, so try CCCallFuncN instead. Hope everything goes well.

• What is "the problem"? Why does using CCCallFuncN instead of CCCallFunc fix it? – yoozer8 Mar 30 '12 at 0:44
• CCCallFunc calls a selector, CCCallFuncN calls a selector with the Node as a parameter. As I understand it, if you just need to run a method, CallFunc is fine, but if you need to run something for this element (that just finished moving, say) then you use CallFuncN so you have a reference to that node. – Brian Broom Dec 17 '12 at 10:32