Question

Hello I am making a side scrolling cocos2d app where enemies attack a character. I am using arc4random and a switch statement to spawn the enemies one at a time. This should happen but it instead spawns two at a time. I am a beginner in cocos2d and objective c so I may be missing something simple. Any help is valuable though.

Here is the code:

#import "FlyingEnemy.h"

@implementation FlyingEnemy
+(id)createEnemies{
return [[[self alloc]init]autorelease];
}

-(id)init{
if((self = [super init])){
    CGSize size = [[CCDirector sharedDirector]winSize];
    screenWidth = size.width;
    screenHeight = size.height;

    screenBounds = [[UIScreen mainScreen] bounds];

    redEnemyFlameCounter = 1;

    xPoint = screenWidth - 50;
    yPoint = screenHeight/2;

    yellowEnemyFlameCounter = 1;

    blueEnemyFlameCounter = 1;

    xPointBlueEnemy = screenWidth - 50;
    yPointBlueEnemy = screenHeight - 50;

    [self createEnemyOfType];
}
return self;
}

-(void) createEnemyOfType{
randomEnemy = arc4random_uniform(4);
CCLOG(@"the number is %i",randomEnemy);
switch(randomEnemy) {
    case 0: isRedEnemyOnTheScreen = YES;

            redEnemy = [CCSprite spriteWithFile:@"redenemy.png"];
            redEnemy.position = ccp(xPoint, yPoint);
            [self addChild:redEnemy z:-1];

            [self schedule:@selector(shootTheBullets:)interval:1.0f/2.0f];

            [self schedule: @selector(removeTheEnemy:)interval:18.0f/1.0f];

            [self schedule: @selector(redEnemyFlame:)interval:1.0f/5.0f];

        CCLOG(@"number = %i",randomEnemy);
        break;
    case 1: isYellowEnemyOnTheScreen = YES;

            yellowEnemy = [CCSprite spriteWithFile:@"yellowenemy.png"];
            yellowEnemy.position = ccp(screenWidth - 50, 50);
            [self addChild:yellowEnemy z:-1];

            yellowEnemyMoveDown  = [CCMoveTo actionWithDuration:2.0 position:ccp(yellowEnemy.position.x, 50)];
            yellowEnemyMoveUp = [CCMoveTo actionWithDuration:2.0 position:ccp(yellowEnemy.position.x, screenHeight/2)];
            yellowEnemyFloatingSequnece = [CCSequence actions:yellowEnemyMoveUp, yellowEnemyMoveDown, nil];
            yellowEnemyFloatingRepeat = [CCRepeat actionWithAction:yellowEnemyFloatingSequnece times:2];
            [yellowEnemy runAction:yellowEnemyFloatingRepeat];

            [self schedule: @selector(yellowEnemyFlame:)interval:1.0f/5.0f];

        CCLOG(@"number = %i",randomEnemy);
        break;
    case 2: isBlueEnemyOnTheScreen = YES;

            blueEnemy = [CCSprite spriteWithFile:@"blueenemy.png"];
            blueEnemy.position = ccp(xPointBlueEnemy, yPointBlueEnemy);
            [self addChild:blueEnemy z:-1];

            [self schedule:@selector(shootTheWaterBullets:)interval:1.0f/2.0f];

            CCMoveTo* blueEnemyMoveDown = [CCMoveTo actionWithDuration:3.0 position:ccp(xPointBlueEnemy, 70)];
            CCMoveTo* blueEnemyMoveUp = [CCMoveTo actionWithDuration:3.0 position:ccp(xPointBlueEnemy, screenHeight - 100)];
            CCSequence* blueEnemyFloatingSequence = [CCSequence actions:blueEnemyMoveDown, blueEnemyMoveUp, nil];
            CCRepeat* blueEnemyFloatingRepeat = [CCRepeat actionWithAction:blueEnemyFloatingSequence times:3];
            [blueEnemy runAction:blueEnemyFloatingRepeat];

            [self schedule: @selector(removeTheBlueEnemy:)interval:18.0f/1.0f];

            [self schedule: @selector(blueEnemyFlame:)interval:1.0f/5.0f];

        CCLOG(@"number = %i",randomEnemy);
        break;
    case 3 : isSpinningRockOnTheScreen = YES;

            spinningRock = [CCSprite spriteWithFile:@"rocks.png"];
            spinningRock.position = ccp(screenWidth * 1.5, screenHeight/2);
            [self addChild:spinningRock z:-1];

            [spinningRock runAction:[CCRepeatForever actionWithAction:[CCRotateBy actionWithDuration:2.0 angle:360]]];

            moveTheRock = [CCMoveTo actionWithDuration:39.0 position:ccp(-500, spinningRock.position.y)];
            [spinningRock runAction:moveTheRock];

            [self schedule:@selector(removeTheSpinningRock:)interval:10.0f/1.0f];

        CCLOG(@"number = %i",randomEnemy);
        break;
}
}

-(void)removeTheSpinningRock:(ccTime)delta{
[self unschedule:@selector(removeTheSpinningRock:)];
[self stopAllActions];

[self createEnemyOfType];

isSpinningRockOnTheScreen = NO;
}

-(void)redEnemyFlame:(ccTime)delta{
redEnemyFlameCounter ++;

if (redEnemyFlameCounter % 2){
    [redEnemy setTexture:[[CCSprite spriteWithFile:@"redenemy2.png"]texture]];
}else{
    [redEnemy setTexture:[[CCSprite spriteWithFile:@"redenemy.png"]texture]];
}
}

-(void)removeTheEnemy:(ccTime)delta{
CCMoveBy* moveUp = [CCMoveBy actionWithDuration:2.0 position:ccp(100, screenHeight/2)];
[redEnemy runAction:moveUp];
[self unschedule:@selector(removeTheEnemy:)];

[self createEnemyOfType];

isRedEnemyOnTheScreen = NO;
}

-(void)yellowEnemyFlame:(ccTime)delta{
yellowEnemyFlameCounter ++;

if (yellowEnemyFlameCounter % 2){
    [yellowEnemy setTexture:[[CCSprite spriteWithFile:@"yellowenemy2.png"]texture]];
}else{
    [yellowEnemy setTexture:[[CCSprite spriteWithFile:@"yellowenemy.png"]texture]];
}
[self schedule:@selector(yellowEnemyFlight:)interval:8.0f/1.0f];

}

-(void)yellowEnemyFlight:(ccTime)delta{
yellowEnemyMoveLeft = [CCMoveTo actionWithDuration:4.0 position:ccp(-100, bulletY)];
[yellowEnemy runAction:yellowEnemyMoveLeft];

[self schedule:@selector(removeTheYellowEnemy:)interval:4.0f/1.0f];
}

-(void)removeTheYellowEnemy:(ccTime)delta{
CCMoveTo* removeYellowEnemy = [CCMoveTo actionWithDuration:1.0 position:ccp(-100, screenHeight/2)];
[yellowEnemy runAction:removeYellowEnemy];
[self unschedule:@selector(removeTheYellowEnemy:)];

[self createEnemyOfType];

isYellowEnemyOnTheScreen = NO;
}

-(void)blueEnemyFlame:(ccTime)delta{
blueEnemyFlameCounter ++;

if (blueEnemyFlameCounter % 2){
    [blueEnemy setTexture:[[CCSprite spriteWithFile:@"blueenemy2.png"]texture]];
}else{
    [blueEnemy setTexture:[[CCSprite spriteWithFile:@"blueenemy.png"]texture]];
}
}

-(void)removeTheBlueEnemy:(ccTime)delta{
CCMoveBy* moveUpBlueEnemy = [CCMoveBy actionWithDuration:0.5 position:ccp(200, 400)];
[blueEnemy runAction:moveUpBlueEnemy];
[self unschedule:@selector(removeTheBlueEnemy:)];

[self createEnemyOfType];

isBlueEnemyOnTheScreen = NO;
}
@end
Was it helpful?

Solution

When you call your removeEnemy method, you don't call a corresponding method to remove your child sprite from the scene. Therefore, every time you call that method another CCSprite gets added without one being removed, which is why you are seeing duplicates. Make sure you call removeChild: to remove the CCSprite.

OTHER TIPS

If u have a bad access it means your object is nill or if u removed your object from scene and after this u are trying to do something with this object, for example run action on it, it's bad access.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top