Dispenser/States/ServeState.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
A state for use in a dispenser's state machine. This state dispenses water from the dispenser. It plays a brief dispensing animation before exiting. |
*/ |
import SpriteKit |
import GameplayKit |
class ServeState: DispenserState { |
// MARK: Properties |
/// A multiplier for the speed of the dispensing animation. |
static let timeScale = 0.5 |
// MARK: Initialization |
required init(game: GameScene) { |
super.init(game: game, associatedNodeName: "ServeState") |
} |
// MARK: GKState overrides |
override func didEnter(from previousState: GKState?) { |
super.didEnter(from: previousState) |
playDispensingAnimationThenExit() |
} |
override func isValidNextState(_ stateClass: AnyClass) -> Bool { |
/* |
This state can only transition to the partially full and empty |
states. |
*/ |
switch stateClass { |
case is PartiallyFullState.Type, is EmptyState.Type: |
return true |
default: |
return false |
} |
} |
// MARK: Other Game Logic |
/** |
Creates and plays the dispensing animation, then tells the state |
machine to enter the empty or partially full state, depending on the |
resultant water level. |
*/ |
func playDispensingAnimationThenExit() { |
// These nodes create base actions to be run on nodes in the scene. |
let slideCupAction = SKAction(named: "slideCup", duration: 3 * ServeState.timeScale)! |
let fillCupAction = SKAction(named: "fillCup", duration: 2 * ServeState.timeScale)! |
let resetStreamAction = SKAction(named: "resetStream", duration: 0)! |
let resetCupAction = SKAction(named: "resetCup", duration: 0)! |
let drainWaterAction = SKAction(named: "drainWater", duration: ServeState.timeScale)! |
// These nodes run an action on a node. |
let slideCupActionOnNode = SKAction.run(slideCupAction, onChildWithName: "//bottle") |
let fillCupActionOnNode = SKAction.run(fillCupAction, onChildWithName: "//stream") |
let resetStreamActionOnNode = SKAction.run(resetStreamAction, onChildWithName: "//stream") |
let resetCupActionOnNode = SKAction.run(resetCupAction, onChildWithName: "//bottle") |
let drainWaterActionOnNode = SKAction.run(drainWaterAction, onChildWithName: "//water") |
// This action inserts a delay into a sequence. |
let waitAction = SKAction.wait(forDuration: ServeState.timeScale) |
// This action defines a timed sequence of events. |
let innerSequence = [ |
waitAction, |
drainWaterActionOnNode, |
waitAction, |
resetStreamActionOnNode, |
waitAction, |
resetCupActionOnNode |
] |
let innerSequenceAction = SKAction.sequence(innerSequence) |
// This action defines a group of actions to play simultaneously. |
let group = [slideCupActionOnNode, fillCupActionOnNode, innerSequenceAction] |
let groupAction = SKAction.group(group) |
// Play the dispensing animation, then exit conditionally. |
game.scene?.run(groupAction, completion: { |
let waterNode = self.game.childNode(withName: "//water") as! SKSpriteNode |
if waterNode.size.height < 1 { |
self.stateMachine?.enter(EmptyState.self) |
} |
else { |
self.stateMachine?.enter(PartiallyFullState.self) |
} |
}) |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13