The purpose of the game will be to drop your balls in such a way that they land in good slots and not bad ones. We have bouncers in place, but we need to fill the gaps between them with something so the player knows where to aim.
We'll be filling the gaps with two types of target slots: good ones (colored green) and bad ones (colored red). As with bouncers, we'll need to place a few of these, which means we need to make a method. This needs to load the slot base graphic, position it where we said, then add it to the scene, like this:
func makeSlot(at position: CGPoint, isGood: Bool) {
var slotBase: SKSpriteNode
if isGood {
slotBase = SKSpriteNode(imageNamed: "slotBaseGood")
} else {
slotBase = SKSpriteNode(imageNamed: "slotBaseBad")
}
slotBase.position = position
addChild(slotBase)
}
Unlike makeBouncer(at:)
, this method has a second parameter – whether the slot is good or not – and that affects which image gets loaded. But first, we need to call the new method, so add these lines just before the calls to makeBouncer(at:)
in didMove(to:)
:
makeSlot(at: CGPoint(x: 128, y: 0), isGood: true)
makeSlot(at: CGPoint(x: 384, y: 0), isGood: false)
makeSlot(at: CGPoint(x: 640, y: 0), isGood: true)
makeSlot(at: CGPoint(x: 896, y: 0), isGood: false)
The X positions are exactly between the bouncers, so if you run the game now you'll see bouncer / slot / bouncer / slot and so on.
One of the obvious-but-nice things about using methods to create the bouncers and slots is that if we want to change the way slots look we only need to change it in one place. For example, we can make the slot colors look more obvious by adding a glow image behind them:
func makeSlot(at position: CGPoint, isGood: Bool) {
var slotBase: SKSpriteNode
var slotGlow: SKSpriteNode
if isGood {
slotBase = SKSpriteNode(imageNamed: "slotBaseGood")
slotGlow = SKSpriteNode(imageNamed: "slotGlowGood")
} else {
slotBase = SKSpriteNode(imageNamed: "slotBaseBad")
slotGlow = SKSpriteNode(imageNamed: "slotGlowBad")
}
slotBase.position = position
slotGlow.position = position
addChild(slotBase)
addChild(slotGlow)
}
That basically doubles every line of code, changing "Base" to "Glow", but the end result is quite pleasing and it's clear now which slots are good and which are bad.
We could even make the slots spin slowly by using a new class called SKAction
. SpriteKit actions are ridiculously powerful and we're going to do some great things with them in later projects, but for now we just want the glow to rotate very gently.
Before we look at the code to make this happen, you need to learn a few things up front:
CGFloat.pi
.CGFloat
is yet another way of representing decimal numbers, just like Double
and Float
. Behind the scenes, CGFloat
can be either a Double
or a Float
depending on the device your code runs on. Swift also has Double.pi
and Float.pi
for when you need it at different precisions.repeatForever()
method, then run that.Our new code will rotate the node by 180 degrees (available as the constant CGFloat.pi
or just .pi
) over 10 seconds, repeating forever. Put this code just before the end of the makeSlot(at:)
method:
let spin = SKAction.rotate(byAngle: .pi, duration: 10)
let spinForever = SKAction.repeatForever(spin)
slotGlow.run(spinForever)
If you run the game now, you'll see that the glow spins around very gently. It's a simple effect, but it makes a big difference.
SAVE 50% To celebrate Black Friday, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.