We are going to create a version of a label that will countdown from a specified number. To do this we subclass the SKLabelNode class, and add some functionality of our own. The advantage of doing this is that we could later reuse the same class in another game if we wanted to.
SKLabelNode
. Replace the existing code in the file with the following:
import SpriteKit
class CountdownLabel: SKLabelNode{
}
func update(){
}
func startWithDuration(duration: TimeInterval){
}
func hasFinished() -> Bool{
//for now return false to avoid seeing a warning
return false
}
var endTime:Date!
endTime
instance variable. Add the following code inside the startWithDuration
method to do that:
let timeNow = Date()
endTime = timeNow.addingTimeInterval(duration)
private func timeLeft() -> TimeInterval{
let now = Date();
let remainingSeconds = endTime.timeIntervalSince(now)
return max(remainingSeconds, 0)
}
update
method, add the following code:
//convert remaining time to an integer
let timeLeftInteger = Int(timeLeft())
//update the label text, converting the Int to a String
text = String(timeLeftInteger)
hasFinished
method with that shown below to check if the timer has reached zero:
return timeLeft() == 0
import SpriteKit
class GameScene: SKScene {
//create a variable for the time and instantiate it
let timer = CountdownLabel()
override func didMoveToView(view: SKView) {
//create, position and start the time when the game moves to the view
let centre = CGPoint(x: frame.midX, y: frame.midY)
timer.position = centre
timer.fontSize = 65
addChild(timer)
timer.startWithDuration(duration: 20)
}
override func update(_ currentTime: TimeInterval) {
//tell the timer to update
timer.update()
}
}
Note that the
override
keyword is used to signify that we are
overriding functionality which is implemented in a parent class (in this case the SKScene class). Sometime we need to use both sets of functionality and we should therefore call the method from the parent class (in this example we might call
super.didMoveToView()
).
We can turn the time into a very simple game to see how many times we can tap a button in a short space of time. To do this, we need to add a button (e.g. a SpriteNode) and a score (e.g. a LabelNode) to the scene, and also keep track of the high score.
var highScore = 0
let scoreLabel = SKLabelNode()
let button = SKSpriteNode()
We will use these to keep track of the score, display the high score, and allow the user to play the game respectively.
func setupButton(){
button.size = CGSize(width: 100, height: 100)
var x = frame.midX
var y = frame.midY - 150
button.position = CGPoint(x: x,y: y)
button.color = UIColor.red
addChild(button)
}
func setupScoreLabel(){
var x = frame.midX
var y = frame.midY + 150
scoreLabel.position = CGPoint(x: x, y: y)
scoreLabel.horizontalAlignmentMode = .right
scoreLabel.text = "0"
addChild(scoreLabel)
}
func updateScoreLabel(){
scoreLabel.text = String(highScore)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//check the timer has not finished
if !timer.hasFinished(){
//go through all the possible touches
for touch in touches{
//if a touch is inside the button
if button.frame.contains(touch.location(in: self)){
//increment the high score and update the label
highScore += 1
updateScoreLabel()
}
}
}
}
didMove(to view:)
method
setupButton()
setupScoreLabel()
You should now be able to run the game, though you may want to shorten the length of time the timer runs to make the game easier (and more comfortable) to play! You can download a completed version of this from GitHub
Implement different levels with varying size buttons, moving buttons or varying periods of time, along with a target number of presses for each level.