3

現在、ゲーム内でスプライトが別のスプライトと衝突すると、パーティクル エフェクトが表示されます。

私はこのコードスニペットを持っています:

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

作成したパーティクルの発生率は 1000 で、最大 100 です。パーティクル エミッタ ノードの位置を、スプライトが現在画面上にある場所に設定します。次に、パーティクル レイヤー ノードの子として追加します。

私の質問は、終了後にパーティクル エミッタ ノードをその親から手動で削除する必要がありますか? それとも、スプライト キットは、再生が終了すると自動的に削除されますか?

私のプロジェクトはスプライト同士が頻繁に衝突するように設計されているため、メモリ リークを防ぐためにこれを手動で処理する必要があるかどうかを確認したいと思います (既に再生が終了した子エミッタ ノードが多数あるパーティクル レイヤー)。

4

2 に答える 2

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];
于 2015-02-03T22:43:59.487 に答える