I really love cocos2d and everything has worked out perfectly until now. I am making a game using runtime procedural generation and every time the step function is called I run loops, going through each of my arrayed sprites. This has worked fine, but when I added in a loop call which was based on time(doe below) the loop runs and adds the explosion, but then does not remove the sprite or tile(subclass of CCSprite, which includes CCSprite, cpShape, cpBody ). The weird thing about this is it will let me run other functions on the tile, such as repositioning it, but won't let me remove it. Sometimes it gives me the error that I am removing the chipmunk static shape twice. When I remove this, however, it still quits on the "[self removeChild: tile.sprite...];. I would appreciate any help.
Here is the code:
for (Tile *tile in BridgeBuilder) {
if (snazzy.position.x+160 >= tile.sprite.position.x && snazzy.position.x+120 <= tile.sprite.position.x) {
for (CCSprite *sprite in DynamiteBuilder) {
if (sprite.position.x == tile.sprite.position.x) {
int timeremove = (arc4random()%4+1);
int delaytimeremove = timeremove*4;
x1 = tile.sprite.position.x;
CCAnimation * animation2 = [[CCAnimation alloc] initWithName:@"Explode" delay:timeremove/6.0];
for ( int n=1; n < 5; ++n )
{
NSString * fname2 = [NSString stringWithFormat:@"Explosion%i.png", n];
[animation2 addFrame:[explosioncache spriteFrameByName: fname2]];
}
//I have tried CCCallFunc and it leaves me with the same result
id explosionAnimo = [CCSequence actions: [CCSpawn actions:[CCAnimate actionWithAnimation:animation2],
[CCDelayTime actionWithDuration:delaytimeremove/6.0], nil],
//[CCSpawn actions:[CCCallFunc actionWithTarget:self selector:@selector(explosion:)],
//[CCCallFunc actionWithTarget:self selector:@selector(Dynamiteexplosion:)],nil],
nil];
[sprite runAction:explosionAnimo];
[self performSelector:@selector(explosion:) withObject:nil afterDelay:delaytimeremove/6.0];
}
}
}
}
Then it calls this function:
//It would really helpful if someone could show my a how to make a function that removes and sprite when called.
-(void)explosion:(id)sender{
for (Tile *tile1 in BridgeBuilder) {
if (tile1.sprite.position.x == x1) {
CCParticleExplosion *explosion = [CCParticleExplosion node];
explosion.position = cpv(x1,tile1.sprite.position.y+60);
explosion.gravity = cpv(0, -300);
[self addChild:explosion];
cpSpaceRemoveStaticShape(space, tile1.shape);
cpShapeFree(tile1.shape);
[BuildingBuilder removeObjectAtIndex:0];
[self removeChild: tile1.sprite cleanup:YES];
[tile1 release];
}
}
for (CCSprite *sprite1 in DynamiteBuilder){
if (sprite1.position.x == x1) {
[DynamiteBuilder removeObjectAtIndex:0];
[self removeChild:sprite1 cleanup:YES];
}
}
}
Thanks,
Weird Loops and Cocos2d
(7 posts) (4 voices)-
Posted 1 year ago #
-
Oh and by the way I have run a loop to remove unused sprites and it works here is the code:
for (Tile *tile in BuildingBuilder) {
if (snazzy.position.x-360 >= tile.sprite.position.x) {
cpSpaceRemoveStaticShape(space, tile.shape);
cpShapeFree(tile.shape);
tile.shape = nil;
[self removeChild:tile.sprite cleanup:YES];
[BuildingBuilder removeObjectAtIndex:0];
[tile release];
}
}
Thanks again for any help.Posted 1 year ago # -
I don't think it's safe to remove anything from a collection within a loop that iterates the collection unless you iterate backwards. You could try adding the objects you want to remove to a separate array and then remove those after your initial loop.
Also (unrelated to your problem) you should add your code between backticks - makes it easier to read.
Posted 1 year ago # -
@G-Ram,
I think it's recommended to remove Chipmunk shapes and bodies in a postStepCallback. Chipmunk Collision Callbacks
-Mark
Posted 1 year ago # -
Thanks so much Chrisco and Mark. I think I will try to do what Chrisco said and the objects I want to remove to an array and then final remove them using something like LastObject.
Posted 1 year ago # -
You should also keep what @Mark said in mind as well - I'm not really up on Chipmunk stuff, so I don't want to lead you too far astray :) A good rule of thumb in general though is to watch what you do with a collection when iterating through it. Very easy to shoot yourself in the foot :)
Posted 1 year ago # -
btw: wrapping you're code in backticks ( ` ) makes it a lot easier to read :)
Posted 1 year ago #
Reply
You must log in to post.