【アプリ開発】初心者のiPhoneアプリ開発入門 その7 縦スクロールとスワイプ(フリック)機能の実装
【スポンサーリンク】
前回は量的な問題で見送った下記の実装を今回はやっていく。
- 縦スクロール
- スワイプ(フリック)の取得
縦スクロールは応用すれば横スクロールもでき、スワイプはスマホのアプリで様々な事に使えるので是非この機会にマスターしておきたい所。
目次:
前回のおさらい
前回は下記の記事で背景画像の表示、画像の表示、重なり順序の設定を行った。
これらは今後も必須と言っていいほど使う内容だと思うのでまだ知らない人は読んでみるといいかも。
今回は前回のコードは不要なので新規でプロジェクトを作成してコードを書いていく。
縦スクロールの実装
まずは縦スクロールの実装から。
前回と同様にプロジェクトを作成し、不要なコードを削除してGameScene.swiftを下記の画像の様な状態にしよう。
Warningが出ているが
locationせっかく定義したのに使ってないじゃないかと言われているだけなので気にしないでおこう。
関数を使っていこう
これから先いくつも機能を実装していくにあたって今回から機能ごとに関数を作成して行くことにする。これを行うことにより汎用性が高くなりコードの可読性も向上する。
と言うことで新しく空の関数「scrollBackground」を一番下に記述し、それをdidMovetoViewの最後で呼び出すコードを書いてみよう。
こんな感じだ。
正常に呼びだされているか確認するためにscrollBackgroundの中でprintを記述してログを表示してみた。
右下にscroll backgroundと正常に表示された。
これで正常に関数が呼び出せていることがわかった。
スクロールの実装
スクロールを実装する関数の準備が出来たので実装を進めていく。
予め縦長の背景を適当に落としておこう。背景画像の準備が終わったら下記のようにコードを書いてみよう。
書いた内容としては背景画像を読み込んで初期位置、サイズ、そして名前を設定した。
これで実行すると設定した背景画像が描画される。
次に動かすコードを書いていく。
コードはこんな感じになった。色々と説明はコメントの方に記載してみた。
要は動かし方とリセットの情報を定義してそれを1つにまとめてsequenceに登録するイメージ。SKAction.sequenceの中のwaitForDurationの3秒は画像をスクロールさせてから何秒後にリセットするかの秒数。今回は3秒で背景全体がスクロールする様にしているので同じ3秒を指定した。
実行結果は下記になる。
画像だと解りづらいがちゃんと縦にスクロールできている。
ちなみにこの実装には下記のサイトを参考にした
https://www.hackingwithswift.com/example-code/games/how-to-run-skactions-in-a-sequence
これでスクロールの実装は完成!
フリック(スワイプ)入力の取得
こっちのほうがスクロールよりは簡単だ。
まず2つ変数を定義する。pointBeganとpointEndだ。
この2つの変数はタッチ開始位置とタッチ終了位置を保存させるために使用する。
タッチ開始位置の取得
予め用意されているtouchesBeganの関数の中を下記のように書き換えてみよう。
やっている事としてはタッチされた場所pointBeganに格納し、ループで回しているが1つしかいらないので1つ取得したらbreakを使って抜けだしている。そして最後にprintで値が取れているかをチェック。
このコードを実行すると画像の右下のようにタッチした座標が取得出来る。
タッチした座標が取れたので次はタッチ終了の座標を取る。
これにはtouchesEndedという関数を定義して実装する。座標の取得はtouchesBeganと同じなので下記のように書いてみる。
実行するとタッチしたら2回同じ座標(開始、終了)が表示され、ドラッグすると異なる座標が表示されるようになる。
これでタッチの開始と終了位置の取得が成功した。あとはそれが左右かを判断するだけ。
コードは下記のようになった。
右フリックしたらログにright flickと表示、左にフリックしたらleft flickと表示するようにし、更に横と縦の移動距離も表示するようにした(今回は上下の移動は関係ないので計算には使用していない)。
これでフリックの判定も上手く実装が出来た。
まとめ
今回は少し更新が遅れてしまったので作業していた内容を「こんな感じで実装しましたよー」的な駆け足報告になってしまって全くライブ感がなかったので少し反省。
次回はアニメーションとか衝突判定とかスコアの表示とか画面遷移とかやっていきたい。。。
が、どれも少しずつ実装は進めているのでこれまたライブ感が薄れてしまっているかもしれない。こんな内容でも誰かの問題解決に繋がっていれば幸いだ
ちなみに今回はまったところとしては、最後に移動距離を比較する「minimumDistance」の判定する所で「distanceHorizontal」の型がCGFloatだったために当初Floatで定義していた「minimumDistance」と比較が出来ずにエラーになったところだ。CGFloatとFloatはそのままでは比較出来ないのでどちらかをキャストしてあげる必要があることに注意しよう。
その変数に格納されている値の方を見るときはOptionを押しながらその変数にカーソルを当てることで確認が可能なので気になった時は試してみよう。
今回は以上。
次回は割りと近い人に出来る様に頑張ります。