【Swift】Use SKAction instead of Timer.scheduledTimer for iterative processing in Spritekit!


In this article, I will introduce some of the points I stumbled upon in the process of creating a shooting game in swift, as well as some of the code I struggled to find out.
The article focuses on spritekit, a framework used to create games in swift.

In this article, I'd like to write about how to do repetitive processing in spritekit. When I first started making games, I used Timer.scheduledTimer, which I had read about in a beginner's book, to imitate the repetitive process, but I gradually realized that this timer was causing problems. In addition, once the timer is stopped, it has to be generated again. In this article, I would like to show you how to repeat the process at a certain time without using Timer.scheduledTimer.

I made this game.

First of all, I would like to invite you to play my shooting game and see how I implemented it. It is a 2D vertical scrolling shmups with 6 stages.

The development environment is xcode 12.5 and swift 5.4.

Use SKAction for iterative processing.

In Spritekit, SKAction.repeatForever is used instead of Timer.scheduledTimer when we want to execute a process at a fixed interval or at a specified time. SKAction is often used for enemy sprite movement and firing enemy bullets, and SKAction is executed from the current scene to perform repetitive processing. timer.scheduledTimer can also perform repetitive processing, but I found that it caused problems when screen transitions occurred, such as when the stage changed. SKAction.

let timerWait = SKAction.wait(forDuration: 0.1)  //Set the repetition interval to 0.1 second.
let shotCheck = SKAction.run {
    self.jikiShot()  //Execute shot processing functions.
let shotSequence = SKAction.sequence([shotCheck,timerWait])  //Put the repeated processes in order.
let loopShotCheck = SKAction.repeatForever(shotSequence)  //Specify to repeat forever.
self.run(loopShotCheck) //Run from the current scene

For your information, the repeat() process, which allows you to specify the number of times to repeat, is shown below.

let loopShotCheck = SKAction.repeat(shotSequence, count: 5) // Repeat only five times.

There is also a timer that can be used even when all the nodes are paused, "self.isPause = true", which is often used for pausing in games. However, there is a timer that can be used even when all the nodes are paused. The following code can be used to release isPause after a certain period of time even when all the nodes are paused.

// Execute the process after 10 seconds.
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
            self.isPaused = false //Release the pause of the current scene.

Please give it a try.