SKShapeNode с emiitter аварийно завершает работу с SKAction removeFromParent

У меня есть SKShapeNode с дочерним SKEmitterNode. Я прикрепил последовательность SKAction, где последним действием является removeFromParent. Узел ведет себя правильно без эмиттера, выполняя действие, а затем удаляя себя. Однако, если эмиттер подключен, то вся программа падает (выполнение переходит к основному методу и, кажется, зависает) при удалении шейп-узла.

-(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];
}

Программа будет работать в обоих этих случаях:

  1. Я не прикрепляю излучатель
  2. Я не включаю действие removeFromParent

Я предполагаю, что это сработает, если я прикреплю действие к эмиттеру для удаленияFromParent (скажем, через 0,9 секунды) до того, как шейп-узел будет удален, но это кажется утомительным долгосрочным решением.

Кто-нибудь знает, что происходит с узлом с дочерними узлами, где removeFromParent применяется к родительскому узлу, или как я могу решить эту проблему?


Обновление на основе ответа LearnCocos2D

В моем полном коде я фактически создаю один лазер, как указано выше, а затем копирую его на второй лазер. Я использовал приведенный ниже код LearnCocos2D, который работает для одного лазера, но не работает для двух. Важные изменения для моего кода, основанные на ответе LearnCocos2D:

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

Присвоение имени Laserfire и удаление его из родителя на основе этого имени работает при клонировании лазера для использования, когда я хочу, чтобы несколько лазеров запускались одновременно.


person Zack    schedule 16.11.2013    source источник


Ответы (2)


Я могу подтвердить, что это сбой. Я разработал решение, которое работает. Если вы удалите эмиттер до удаления узла формы, сбой исчезнет:

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]];

Когда отчеты об ошибках Apple появятся в сети, я сообщу об этом как об ошибке. Я не могу объяснить, почему это может рухнуть.

person LearnCocos2D    schedule 16.11.2013
comment
Это работает для одного лазера, что и указано в моем примере. В своем полном коде я создаю лазер1, добавляю эмиттеры и действия к лазеру1, затем копирую лазер1 в новый лазер2. Второй лазер по-прежнему вызывает сбой. См. мой отредактированный вопрос для моего решения на основе вашего кода здесь. - person Zack; 17.11.2013
comment
Большое спасибо - я несколько дней бился об этом, прежде чем нашел это. Я не могу понять, почему он падает на некоторых, а не на других. - person avance; 28.01.2014

Я столкнулся с этим, когда к спрайту было подключено более одного эмиттера. Уловка, которую я нашел, заключалась в том, чтобы дать каждому эмиттеру собственное имя после добавления его к родителю. Кажется, что SpriteKit должен использовать это имя внутри, когда он удаляется из родителя.

person Chris Garrett    schedule 23.08.2014