前回の記事
【GameplayKit】iOSゲームアプリにおけるStateパターン実践 Part_5では、ステートマシンによるステート遷移に分岐構造を実装しました。
この記事について
今回は、ステートパターンとはあまり関係がなくなってしまうかもしれませんが、SpriteKit
のレンダリング概念について実践しながら理解していきます。
ここまでの記事で、「給水機は満タン > 給水 > タンク水量が減少 > カラ状態」までをステート遷移できるようになりました。さらに、それぞれのアニメーションはスプライトノードのアクション機能を使用して実現しました。
この記事では、給水機がカラ状態EmptyState
になった後に補給(リフィル)されて、タンク水量が増加していく様をレンダリングします。
手順
大まかな流れは以下のようになります。
給水機の表示ランプを点滅させる
給水機の表示ランプを点滅させる
タンクが空になったら、表示ランプをチカチカ点滅させます。
class EmptyState: DispenserState {
var flashTimeCounter: TimeInterval = 0
static let flashingInterval: TimeInterval = 0.6
var lightOn = true {
didSet {
let color = (lightOn ? SKColor.red : SKColor.black)
changeIndicatorLightToColor(color)
}
}
...
override func update(deltaTime seconds: TimeInterval) {
flashTimeCounter += seconds
if flashTimeCounter > EmptyState.flashingInterval {
lightOn = !lightOn
flashTimeCounter = 0
}
}
}
flashTimeCounter
プロパティは経過時間を計測します。
flashingInterval
プロパティは点滅させる間隔です。
lightOn
プロパティは計算プロパティです。
update(deltaTime)
メソッドは、ゲームシーンのフレームが描画されるたびに実行されます。
ゲームシーンのレンダリング
シーンのupdate
メソッドで、ステートマシンのupdate(deltaTime)
メソッドを呼び出します。
class GameScene: SKScene {
var stateMachine: GKStateMachine!
var previousUpdateTime: TimeInterval = 0
override func didMove(to view: SKView) {
...
}
override func update(_ currentTime: TimeInterval) {
let timeSincePreviousUpdate = currentTime - previousUpdateTime
stateMachine.update(deltaTime: timeSincePreviousUpdate)
previousUpdateTime = currentTime
}
...
}
update
メソッドでは、最後に描画更新した日時と現在日時の差分(どれくらい時間が経ったか)を引数にしてステートマシンに渡しています。
ビルド
シミュレータでビルドします。
EmptyState
になるまで給水をして、タンクを空にします。
給水機の表示ランプが0.6秒ごとに点滅することが確認できます。
次回
【GameplayKit】iOSゲームアプリにおけるStateパターン実践 Finalでは、ステートマシンの挙動を完成させます。