user1889036
user1889036

Reputation: 13

How to add a CCsprite to layer from array

Hi guys I really need some help, I have been stuck in this part of my game for over a week now and I can't seem to get past this issue, So have look at my code below,

#import "HelloWorldLayer.h"
#import "AppDelegate.h"

@implementation HelloWorldLayer

+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}

-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
    moles = [[NSMutableArray alloc] init];
    winSize = [[CCDirector sharedDirector]winSize];
    CCSprite *mole1 = [CCSprite spriteWithFile:@"lightsabericonblue.png"];


   [self starCreateCurrentLevel:mole1];


}
return self;
}


-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {

    [moles addObject:mole1];        
    starCountCurrentLevel--;

}

[self schedule:@selector(tryPopMoles:) interval:1];

}


- (void)tryPopMoles:(ccTime)dt {
if(moles.count !=   0){
    for (CCSprite *mole in moles) {
        if (arc4random() % moles.count == 0) {
                    if (mole.numberOfRunningActions == 0) {
                        [self popMole:mole];
                    }
        }
    }


}else if(moles.count == 0){
    NSLog(@"No More Moles To Spawn");
    [self unschedule:@selector(tryPopMoles:)];
}

}

- (void) popMole:(CCSprite *)mole {
mole.position = ccp(150, 150);
[self addChild:mole];  
}



- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}

@end

When I run this code i get the following error, * Assertion failure in -[HelloWorldLayer addChild:z:tag:], /Users/....../libs/cocos2d/CCNode.m:335.

I when i add the child in the init method its fine but I don't want to do that, I want to be able to call the try pop mole which will then call the pop mole based on if there is anymore sprites left in the array, I have a feeling I am missing something or doing something wrong.

UPDATE -

#import "HelloWorldLayer.h"
#import "AppDelegate.h"

#pragma mark - HelloWorldLayer
CGSize winSize;
int enemyX;
int enemyY;
int randomAngleY;
int randomAngleX;
int winSizeX;
int winSizeY;
int minDuration = 1;
int maxDuration = 4.0;
int rangeDuration;
int actualDuration;
int starCountCurrentLevel;
int test = 0;

@implementation HelloWorldLayer

+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}


-(id) init
{
if( (self=[super init]) ) {

moles = [[NSMutableArray alloc] init];
winSize = [[CCDirector sharedDirector]winSize];
[self starCreateCurrentLevel];

}
return self;
}

-(void)starCreateCurrentLevel{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
[moles addObject:[CCSprite spriteWithFile:@"lightsabericonblue.png"]];
starCountCurrentLevel--;
}
[self schedule:@selector(tryPopMoles:) interval:3];

}

- (void)tryPopMoles:(ccTime)dt {
 NSMutableArray *tempArray = [NSMutableArray arrayWithArray:moles];
for (int randomIndex = tempArray.count -1; randomIndex < tempArray.count; randomIndex--) {
        CCSprite * sprite = (CCSprite *)[tempArray objectAtIndex:randomIndex];
        //CCSprite *sprite = [tempArray objectAtIndex:randomIndex];
        [self popMole:sprite];
        NSLog(@"Enemy Added");
        [tempArray removeObject:sprite];
    }
 if([tempArray count] == 0){
    NSLog(@"No More Moles To Spawn");
    [self unschedule:@selector(tryPopMoles:)];
}


}

- (void) popMole:(CCSprite *)sprite {

winSizeX = winSize.width - sprite.contentSize.width + 25;
winSizeY = winSize.height - 25 - sprite.contentSize.height + 17;
randomAngleX = arc4random() % winSizeX;
randomAngleY = arc4random() % winSizeY;
enemyX = arc4random() % winSizeX ;
enemyY = arc4random() % winSizeY;
rangeDuration = maxDuration - minDuration;
actualDuration = (arc4random() % rangeDuration) + minDuration;
sprite.position = ccp(enemyX, enemyY);
[self addChild:sprite];

}


- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}

@end

Upvotes: 1

Views: 559

Answers (1)

So Much Drama Studios
So Much Drama Studios

Reputation: 181

You're only creating the sprite once, but trying to add it several times. (Remember, these are pointers to objects, so you're always referring to exactly the same sprite.) If you want 10 versions of the same sprite (at different positions, scales, speeds, whatever), you'll need to create the sprite (via the creator method) 10 times. You can do a copy on the original one, or just create it on the fly:

-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {

    //[moles addObject:mole1];  
    // ^^ You're adding the same sprite (meaning same pointer reference) again and again.  Try this instead:
    [moles addObject:[CCSprite spriteWithFile:@"lightsabericonblue.png"]];      

    starCountCurrentLevel--;
}

Of course, now you don't need to pass mole1 into your method. You may (depending on your need) consider passing in a spriteFrameName or something.

Upvotes: 1

Related Questions