【Swift】ジャンプアニメーションを作ろう！


# はじめに
タップゲーム開発において，ジャンプアニメーションは欠かせません．
よく使うアニメーションの基本を押さえつつ，自分好みにアレンジしていきましょう！

この記事で扱っていないアニメーションは，こちらにわかりやすくまとまっていますので，おすすめです！
[iOSアプリ開発でアニメーションするなら押さえておきたい基礎](https://qiita.com/hachinobu/items/57d4c305c907805b4a53)

# 実装
## 準備
`Main.storyboard`に，ジャンプ機能をもつ**ボタン**とジャンプさせる**プレイヤー画像**を配置しましょう．
<img width="601" alt="スクリーンショット 2019-06-04 11.07.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/2c181a10-da71-ede2-2764-7a73e922fb52.png">

`ViewController.swift`で，宣言したら関連付けもお忘れなく！

```ViewController.swift
import UIKit

class GameDemoViewController: UIViewController {
    
    //使う部品をここに宣言！
    @IBOutlet var playerImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    //ジャンプボタンを宣言！
    @IBAction func jump(){
        //ここにボタンを押したときにすることを書くよ

    }
}
```

## アニメーションの実装
まずはアニメーションの使い方を簡単に説明していきます．

```ViewController.swift

  //ジャンプボタンを宣言！
  @IBAction func jump(){

      UIView.animate(withDuration: 1.0, //アニメーションの継続時間
                     delay: 0.0, //ボタンを押してからアニメーションを開始するまでの時間
                     options: .autoreverse, //逆再生やタイミング曲線などのオプション指定
                     animations: { self.playerImageView.center.y -= 300.0 }, //アニメーションの内容
                     completion: nil //アニメーションが終わったときに何するか
      )
  }
```

`duration`には，アニメーションをして欲しい時間を
`delay`には，ボタンを押してからアニメーションが開始まされるまでの遅延時間を
`options`では,アニメーション中に使用するタイミング曲線の種類（アニメーション中の加速度的な）やアニメーションの逆再生などが指定できます．（`.autoreverse`で逆再生される）
`animations`クロージャ(`{}`)の中には，アニメーションしたい内容を書きます．
`completion`には，アニメーションが再生終わった後にしたい内容を書きます．（`nil`は何もしない．）

一度これでRunして見ましょう！
今は，1秒でプレイヤー画像が上に300pt移動して，逆再生するだけのアニメーションです．
こんな感じになりましたか？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/ed7e8b36-4432-4c67-9bfb-153b46c79c25.gif" width=50%>

ジャンプできてますね！
でも，プレイヤーがどんどん上に行ってしまいます．これはアニメーションが終わったときに初期位置に戻るという設定をしていないからです． `competion`のところを以下のように変えてみましょう！

```ViewController.swift

  //ジャンプボタンを宣言！
  @IBAction func jump(){

      UIView.animate(withDuration: 1.0, //アニメーションの継続時間
                     delay: 0.0, //ボタンを押してからアニメーションを開始するまでの時間
                     options: .autoreverse, //逆再生やタイミング曲線などのオプション指定
                     animations: { self.playerImageView.center.y -= 300.0 } //アニメーションの内容
      ){ _ in
          self.playerImageView.center.y += 300.0 //アニメーション終了後にする内容
      }
  }
```

さて，こうなりましたか？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/eb1fcfa7-c5bd-ea7e-c2ba-d603a5ca9702.gif" width=50%>

いい感じ！
これでも十分ジャンプできていますが，すごく機械的に感じませんか...？
原因は，アニメーションの速度が一定なことにあります．ここでまるで重力を感じているかのようにアニメーションさせてみましょう！`options`に１つ`.curveEaseOut`を加えます！

```ViewController.swift

  //ジャンプボタンを宣言！
  @IBAction func jump(){

      UIView.animate(withDuration: 1.0, //アニメーションの継続時間
                     delay: 0.0, //ボタンを押してからアニメーションを開始するまでの時間
                     options: [.curveEaseOut, .autoreverse], //逆再生やタイミング曲線などのオプション指定
                     animations: { self.playerImageView.center.y -= 300.0 } //アニメーションの内容
      ){ _ in
          self.playerImageView.center.y += 300.0 //アニメーション終了後にする内容
      }
  }
```

これを実行すると...
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259404/cf397f1b-706d-ab98-5049-7f1b608f4fa6.gif" width=50%>

ほら！上に上がるにつれてスピードがゆっくりに，下に降りてくるにつれてスピードが速くなってますね．
`.curveEaseOut`は，徐々に速度を下げるオプションです．これとは逆に`.curveEaseIn`を指定してあげると徐々に速度が速くなっていくアニメーションになります．

基本的なジャンプアニメーションの説明はここまで！お疲れ様でした^^

## これから
`withDuration`や`animations`，`options`の中身を色々変えてみて，プレイヤーの動く方向や速さがどうなるか実際にやってみましょう！
試行錯誤していく中で，自分の作りたいゲームアプリに最適なジャンプアニメーションがきっと見つかりますよ．