2

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.

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
jm1175
  • 165
  • 10

1 Answers1

2

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.

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • Thanks for the help, this is exactly what I tried to do originally and it wasn't working for me. That being said I just tried it again (literally just uncommented the original code) and it's suddenly working fine... I'll mark this as correct, thanks. – jm1175 Mar 26 '17 at 11:36
  • @jm1175 Maybe something else was the cause of lag. You know, initialization of sprites with textures and such. Anyways, glad to hear it worked for you! :) Happy coding. – Whirlwind Mar 26 '17 at 11:43