How to create a continuous “rain” of nodes in SpriteKit
In the last days I am building my first iOS game using Spritekit. During this process, I needed to create a “rain” of objects (nodes) that are generated continuously, frame by frame, like it was actually rain. In a few simple steps, I will show you how to create this type of effect.
#Create a SpriteKit Project
First of all we need to create our Spritekit project. From this template we can delete everything that is useless, such as all the elements inside GameScene.sks.
#Create RainFall.swift
Now we need to create a new class, in my case RainFall, that inherits SKNode. Then we initialize an image: SKSpriteNode, and create a random variable that will be multiplied by the width of the scene. In this way the nodes will spawn randomly over the whole width of the scene. Next we add the physicBody declaring a texture and the dimensions for the node. In addition to dimensions, we also need to create a CategoryBitMask and collisions (later on we will see how to set up them). Now the image is ready to be associated to the node with self.addChild(image).
#Create Floor.swift
Why the “Floor”? The reason is very simple: after the nodes have fallen down, they need to be “destroyed”. Without this destruction the SpriteKit scene will spawn thousand of nodes, causing the crash of the game in a short time. The floor node is very similar to the rain node, the only difference is that the floor will be static and with no texture.
Let’s add another swift file to the project (I named it Floor.swift) and create a new class, in my case Floor, that inherits SKNode.
# Setting up GameScene.swift
Now let’s clean up the class file from everything that is useless for our project. In particular the file GameScene.swift needs only this lines of code:
Before the declaration of the GameScene class, we need to create the BitMasks categories as UInt32 type. It will provide the possibility to detect collisions and decide what the nodes have to do when they get in touch with other nodes.
The last thing to do before adding the floor, is to declare it in the class:
let floor = Floor()
To add it to the scene, we simply write self.addChild(floor) in the DidMove function. Now we need to create a function, in my case spawnRain, in which we will declare our node to be spawned. Let’s associate an image with it and add it to the scene.
Wondering where we will use this feature? Well it is very simple. To spawn nodes continuously, let’s add our function in the override func update.
How to manage the collisions with the floor?
Six lines. Only six line of code are used to detect and manage the collision between the two nodes. Nothing could be easier, right?
#Setting up GameViewController.swift
In this file I usually change the way to consider the size of the scene and the way to present the scene. So I post below the entire viewDidLoad() to show you how to make it works.
#Run
The final hierarchy of our project file is like the screenshot below.
And here the Game finished:
In this way our function will be called whenever the scene updates the frame. We have created a random rain of nodes with minimal effort. Do you still have doubts about the code? Here is the link of the complete project on github.
Thanks for your attention!
Special thanks to Salvatore Emanuele Agosta that always helps me to write articles and with their translation.