вызов метода arc4random для создания одного врага, но вместо этого появляются два

Здравствуйте, я делаю приложение cocos2d с боковой прокруткой, в котором враги атакуют персонажа. Я использую arc4random и оператор switch, чтобы создавать врагов по одному. Это должно произойти, но вместо этого появляется два за раз. Я новичок в cocos2d и Objective c, поэтому я могу упустить что-то простое. Хотя любая помощь ценна.

Вот код:

#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

person PoKoBros    schedule 14.08.2013    source источник
comment
Кажется, в этом коде нет ничего плохого, вы создаете два экземпляра класса FlyingEnemy где-то еще?   -  person Erik Godard    schedule 14.08.2013
comment
Спасибо за быстрый ответ. Я не создаю еще один экземпляр FlyingEnemy где-либо еще. Есть ли другой метод, такой как arc4random, который я могу попробовать, который может быть более надежным?? Есть ли другой способ сделать то, что я делаю??   -  person PoKoBros    schedule 14.08.2013
comment
Я не вижу в этом проблемы, он возвращает только один номер. Два врага одного цвета? Ваши сообщения журнала вызываются дважды?   -  person Erik Godard    schedule 14.08.2013
comment
Все враги разные. В выводе вот что написано. Итак, по какой-то причине arc4random генерирует два числа. 2013-08-13 22:11:37.152 Зак Апп[23917:a0b] число равно 3 2013-08-13 22:11:37.163 Зак Апп[23917:a0b] число = 3 37.163 Приложение Zach[23917:a0b] число равно 1 2013-08-13 22:11:37.166 Приложение Zach[23917:a0b] число = 1   -  person PoKoBros    schedule 14.08.2013


Ответы (2)


Когда вы вызываете свой метод removeEnemy, вы не вызываете соответствующий метод для удаления дочернего спрайта со сцены. Поэтому каждый раз, когда вы вызываете этот метод, добавляется еще один CCSprite без удаления, поэтому вы видите дубликаты. Убедитесь, что вы вызываете removeChild: для удаления файла CCSprite.

person Erik Godard    schedule 14.08.2013
comment
если я помещу removeChild в методы removeTheEnemy, я получу ошибку доступа к потоку. - person PoKoBros; 14.08.2013
comment
Я не могу сказать, как вы объявляете свою переменную redEnemy, но похоже, что сильная ссылка не поддерживается, и переменная выходит за рамки. Вам нужно либо установить строгое @property и оставить там спрайт, либо вы можете дать спрайту тег и таким образом получить к нему доступ. - person Erik Godard; 14.08.2013
comment
Я использовал как теги, так и свойства, и оба они по-прежнему возвращали ошибку неправильного доступа к потоку. - person PoKoBros; 14.08.2013

Если у вас плохой доступ, это означает, что ваш объект нулевой, или если вы удалили свой объект со сцены и после этого пытаетесь что-то сделать с этим объектом, например, выполнить действие над ним, это плохой доступ.

person K1laba    schedule 14.08.2013