完成播放后,我是否必须从父节点手动删除发射器节点?

时间:2015-02-03 19:35:41

标签: ios swift sprite-kit skemitternode

一旦我的精灵与游戏中的另一个精灵发生碰撞,我现在会显示粒子效果。

我有这段代码:

let sparkParticle = SKEmitterNode(fileNamed: "SparkParticle.sks")
if sparkParticle.parent == nil
{
    sparkParticle.position = mySprite.position
    self._particleLayer.addChild(sparkParticle)
}
sparkParticle.resetSimulation()

我创建的粒子的出生率为1000粒子,最大值为100.我将粒子发射器节点的位置设置为我的精灵当前在屏幕上的位置。然后,我将其添加为粒子层节点的子节点。

我的问题是,在完成后,我是否必须从其父节点手动删除它?或者Sprite Kit在播放完毕后会自动将其删除吗?

由于我的项目被设计为让精灵相互碰撞很多,我想确保是否仍然需要手动处理以防止内存泄漏(粒子层有很多子发射器节点已完成已经玩了)

2 个答案:

答案 0 :(得分:0)

简短的回答是,在你的情况下,你不需要担心它。但是,如果粒子发射器不在屏幕上或永久运行,则会成为一个问题。取消分配场景后,将自动删除SKEmitterNode。因为SKEMitterNode是插入节点树的SKNode。

但是,如果您需要格外小心,可以在场景使用以下方法解除分配之前手动并递归停止所有操作和发射器。在场景被取消分配并使我的应用程序崩溃后,我遇到了延迟SKActions触发的问题,因此我在场景被释放之前手动停止它们。

保留对旧场景的引用并在场景中调用:

+(void)recursivelyStopAndRemoveNode:(SKNode*)node {

    // recursively call all children
    for (SKNode *childNode in [node children]) {
        [PCUtils recursivelyStopAndRemoveNode:childNode];
    }

    // stop emitters
    if ( [node isKindOfClass:[SKEmitterNode class]]) {
        SKEmitterNode* sken = (SKEmitterNode*)node;
        sken.targetNode = nil;
        sken.particleBirthRate = 0;
        NSLog(@"stopping emitter %@", node.name);
    }

    // stop any running actions
    [node removeAllActions];

    // remove me from my parent.
    [node removeFromParent];

}

然后,在GameViewController或任何改变场景的地方使用它:

SKScene *oldScene = skView.scene;
[skView presentScene:newScene transition:nil];
if (oldScene) 
   [PCUtils recursivelyStopAndRemoveNode:oldScene];

答案 1 :(得分:0)

我实际上建议您删除发射器。我最近在游戏中遇到了一个问题,因为我没有移除发射器,所以它会开始严重滞后。当添加发射器时,我能够100%重现这个问题,所以我知道它们是帧率下降的唯一原因。在我开始看到滞后之前,它花了大约20个未拆除的发射器。

实际上很容易。您可以创建一个包含等待动作的SKAction序列(1秒或只是效果长度的一部分)和removeFromParent动作。

在完成之后,它将摆脱它,并确保您的帧速率不会下降。