Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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];
[self addChild:enemy];
}

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

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

[enemies addObject:enemy2];

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;
    [self addChild:b];
    [bullets addObject:b];


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.

share|improve this question
5  
-1 use your debugger –  Maik Semder Jul 5 '11 at 7:08
add comment

4 Answers 4

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

share|improve this answer
    
I've never used the xcode debugger. How do I? –  ipodfreak0313 May 10 '11 at 22:44
3  
@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
1  
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
add comment

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];
share|improve this answer
add comment

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.

share|improve this answer
add comment

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

share|improve this answer
1  
What is "the problem"? Why does using CCCallFuncN instead of CCCallFunc fix it? –  Jim 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.