GarySabo
GarySabo

Reputation: 6690

How to switch on score to create an SKEmitterNode using SpriteKit?

I want to be able to toggle my SKEmitterNode (rain particles) off and on based on the score. But my update function gets called constantly, i.e. I end up with millions of particles on the screen with my current code below...how can I structure my code so that the rain particles will only get called once when a score is achieved?

class GameScene: SKScene, SKPhysicsContactDelegate {

         func setUpRain() {
                if let rainParticle = SKEmitterNode(fileNamed: "Rain") {
                    rainParticle.position = CGPointMake(frame.size.width, frame.size.height)
                    rainParticle.name = "rainParticle"
                    rainParticle.zPosition = Layer.Flash.rawValue
                    worldNode.addChild(rainParticle)
                }
            }

            func makeItRain() {
                let startRaining = SKAction.runBlock { 
                    self.setUpRain()
                }
                runAction(startRaining, withKey: "Rain")
            }

            func stopRaining() {
                removeActionForKey("Rain")
                worldNode.enumerateChildNodesWithName("rainParticle", usingBlock: { node, stop in
                    node.removeFromParent()
                })

            }

  }

    class PlayingState: GKState {


        unowned let scene: GameScene  //used to gain access to our scene

        override func updateWithDeltaTime(seconds: NSTimeInterval) {
            scene.updateForegroundAndBackground()
            scene.updateScore()

            if scene.score > 2 {
                scene.makeItRain()

            }

            if scene.score > 4 {
                scene.stopRaining()
            }
        }

Upvotes: 3

Views: 126

Answers (1)

Marshall D
Marshall D

Reputation: 454

There's a few ways you can do this, but the simplest of these is to only call makeItRain() or stopRaining() once per toggle. What I mean by this is once makeItRain is called, it cannot be called again until stopRaining is called. This can be done with a boolean like so:

   var rainToggle: Bool = false; //True = Raining
override func updateWithDeltaTime(seconds: NSTimeInterval) {
                scene.updateForegroundAndBackground()
                scene.updateScore()

                if (scene.score > 4){
                    scene.stopRaining()
                    rainToggle = false;
                }
                else if (scene.score > 2 && !rainToggle) {
                    scene.makeItRain()
                    rainToggle = true;

                }
            }

This is only slightly inefficient since you are calling stopRaining() every frame for no reason, however it gets the job done and is easy to understand. Note also that I had to flip the order in which your if statements came (otherwise it wouldn't work).

Upvotes: 2

Related Questions