swiftsprite-kitsksceneskemitternode

SKEmitterNode disappears when added to a new SKScene


I have a SKEmitterNode that's running on a SKScene and I want to move it to the next SKScene without interrupting the particles.

Normally I'd do it like the following:

let scene: SKScene = GameScene(size: self.size)
let transition = SKTransition.crossFade(withDuration: 0.5)
self.view!.presentScene(scene, transition: transition)

And then on the next SKScene:

override func didMove(to view: SKView) {
    particleEmitter.removeFromParent()
    addChild(particleEmitter)
}

This works perfectly fine however in this situation I don't want to use a transition when moving to the next SKScene. I've tried it without a transition like:

let scene: SKScene = GameScene(size: self.size)
self.view!.presentScene(scene)

And the SKEmitterNode disappears as soon as the new SKScene is presented even though I've removed it from the last SKScene and added it as child to the new one.

My question is why is the SKEmitterNode dissapearing and how can I get it to work without using a transition between the SKScene's. Any help would be much appreciated, thanks.

Note: Using a SKTransition with a duration of 0 also works but this causes a noticeable 'flash' during the transition.


Solution

  • There shouldn't be any flashes and such. If I understand you correctly, what you need to do is to create an emitter in a global scope. Before presenting the next scene, you should remove the emitter from its parent. When you are in the next scene, you add emitter to it. I just tried and it works for me without any lag, flashes or something.

    Here is the code...There are two scenes...A GameScene:

    import SpriteKit
    
    let emitter = SKEmitterNode(fileNamed: "Fireflies")
    
    class GameScene: SKScene {
    
        override func didMove(to view: SKView) {
    
            backgroundColor = .black
    
            if let emitterNode = emitter {
    
                 addChild(emitterNode)
            }
             print("Game Scene")
    
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            if let scene = WelcomeScene(fileNamed: "WelcomeScene") {
    
                scene.scaleMode = .aspectFill
    
                emitter?.removeFromParent()
    
                self.view?.presentScene(scene)
            }
        }
    }
    

    and a WelcomeScene:

    import SpriteKit
    
    class WelcomeScene:SKScene{
    
        override func didMove(to view: SKView) {
    
            backgroundColor = .black
             print("Welcome Scene")
            if let emitterNode = emitter {
                addChild(emitterNode)
    
            }
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            if let scene = GameScene(fileNamed: "GameScene") {
    
                scene.scaleMode = .aspectFill
                emitter?.removeFromParent()
                self.view?.presentScene(scene)
            }
    
        }
    }
    

    For the emitter I've used standard fireflies template.