スイフト(swift)で効率的にアニメーションを表現する方法? | 30歳から始めたプログラミング

スイフト(swift)で効率的にアニメーションを表現する方法?

とりあえず自分の中で結論が出たのでメモしておきます。

 

 

スイフトと言うかアップル製の言語ではゲームで使えそうなアニメーションを作るときはanimateKeyframesWithDurationとその中で使うaddKeyframeWithRelativeStartTimeを利用するのが良いでしょう。

 

これらはキーフレームアニメーションと言って指定した時間内で時間を分割し、順番に連続したアニメーションを動かすことが出来ます。

 

他のアニメーションは1つの動作しか行えないため状況によっては扱い難かったのでキーフレームを選びました

 

基本の形は以下の様な感じ

 

let duration = 10.0 //全体を通した時間(NSTimeInterval型)

let delay = 0.0 //遅延時間(NSTimeInterval型)

let options = .CalculationModeLinear //オプション、いろんなオプションがある

 

UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: {

            UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/10, animations: {

                //0秒から1/10秒(つまり1秒)かけてビューの透明度を1にする

                somethingView.alpha = 1

            })

            UIView.addKeyframeWithRelativeStartTime(1/10, relativeDuration: 5/10, animations: {

               //1/10(つまり1秒目)から5/10秒(つまり5秒)間何もしない

            })

            UIView.addKeyframeWithRelativeStartTime(6/10, relativeDuration: 4/10, animations: {

                //6/10秒(つまり6秒目)から4/10秒(つまり4秒)かけてビューの透明度を0にする

                somethingView.alpha = 0

            })

            }, completion: { finished in

                // 最後に実行する処理

                somethingView.removeFromSuperview() //ビューを削除する

            }

 )

 

上記のように記述すれば連続したアニメーションを順に実行することが出来ます。しかしながら透明度の変更、回転、移動以外は出来ないようで音を鳴らす処理だとかテキストを変更する処理を間に挟んでも無視されすべて0秒目から実行されてしまいます。

 

そこでなにかよい方法は無いかと思い考えたところマルチスレッド機能を使って意図的に遅延実行させてみることにしました

 

具体的には以下のように

 

var seconds: Double = 5

var dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))

dispatch_after(dispatchTime, dispatch_get_main_queue(), {

     //5秒目に行う処理(例えば音を鳴らす処理などを追加する)※コードは割愛

})

seconds = 10

dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))

dispatch_after(dispatchTime, dispatch_get_main_queue(), {

     //10秒目に行う処理(例えばテキストの表示内容を変更する)※コードは割愛

})

 

 

こんな形でコードを書けばアニメーションに合わせてテキストを変更したり、音を鳴らしたりといった表現ができるようになります。ただもしかして微妙に同期がずれて音再生等の処理がズレてしまうかもしれないのでまだまだ改善の余地があるかもしれません。

 

ちなみに私の作った1作目の脱出ゲームの冒頭アニメーションはsleep()とアニメーションと音声再生を組み合わせて作っています。こちらは1つずつ処理を実行するので同期がずれること(音ズレやテキスト変更ズレ)は無いように感じますが全然スマートさが感じられません。

 

しかしスイフト、もう少しなんかなぁ