Question

I have an SKShapeNode with a child SKEmitterNode. I have attached an SKAction sequence where the last action is removeFromParent. The node behaves correctly without the emitter, doing it's action then removing itself. However, if the emitter is attached then the whole program crashes (execution jumps to main method and appears to hang) when the shapenode is removed.

-(void)fireLasers
{
    SKShapeNode* laser1 = [[SKShapeNode alloc] init];
    //laser1 configuration removed for brevity

    NSString *laserParticlePath = [[NSBundle mainBundle] pathForResource:@"LaserParticle" ofType:@"sks"];
    SKEmitterNode *laserFire = [NSKeyedUnarchiver unarchiveObjectWithFile:laserParticlePath];
    [laser1 addChild:laserFire];

    SKAction* s1 = [SKAction moveByX:0 y:1000 duration:1.0];
    SKAction* s2 = [SKAction removeFromParent];

    SKAction* sequence = [SKAction sequence:@[s1, s2]];
    [laser1 runAction:sequence];

    [self.parent addChild:laser1];
}

The program will run in both of these cases:

  1. I do not attach the emitter
  2. I do not include the removeFromParent action

I'm guessing this will work if I attach an action to the emitter to removeFromParent (after say .9 seconds) before the shapenode gets removed, but that seems like a tedious long term solution.

Does anyone know what happens to a node with child nodes where removeFromParent is applied to the parent node, or how I can fix this issue?


Update based on LearnCocos2D's answer

In my full code, I'm actually creating one laser as above, then copying it to a second laser. I used LearnCocos2D's code from below, which works for one laser but fails for two. The important changes for my code, based on LearnCocos2D's answer is:

laserFire.name = @"laserfire";
SKAction* s2 = [SKAction runAction:[SKAction removeFromParent] onChildWithName:@"laserfire"];

Giving laserfire a name and removing it from parent based on that name works when cloning the laser for use when I want multiple lasers fired at once.

Was it helpful?

Solution

I can confirm that this crashes. I devised a solution that works. If you remove the emitter before removing the shape node, the crash goes away:

SKAction* s1 = [SKAction moveByX:0 y:1000 duration:1.0];
SKAction* s2 = [SKAction runBlock:^{
    [laserFire removeFromParent];
}];
SKAction* s3 = [SKAction removeFromParent];

SKAction* sequence = [SKAction sequence:@[s1, s2, s3]];

When Apple's bug reports comes back online I'll report this as a bug. I can't explain why this would crash.

OTHER TIPS

I ran into this when I had more than one emitter attached to a sprite. The trick I found was to give each emitter its own name after adding it to the parent. It seems like SpriteKit must use the name internally when it removes from the parent.

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