part2 「璃奈ちゃんボード」をiPadだけで自作する

#前回のおさらい
* iPadやiPhoneで使える璃奈ちゃんボードを作った！
* 「Rina-chan Board Viewer」の導入から初期設定までを解説！とりあえず「ツナガルコネクト」が再生できた！

https://qiita.com/NSmagnets/items/4753dc28cd50aa6fa12d


#今回のテーマ
* プログラムの仕組みが知りたい
* 「Rina-chan Board Viewer」を使って**自分でスクリプトを書きたい**
* **プリセットに新しい顔を追加したい**
* 璃奈ちゃんボードをもっと自分好みに改造したい

こんな方にオススメです。



#システムの解説
#####ファイル構成のおさらい
　最低限必要なファイルは次の3つです。

* 音楽、セリフ等の**音源**(.mp3,.wav,.aiff等、大体再生出来る)
* 顔を表示するための**スクリプト**(.csv)
* 顔データの**プリセット**(.csv筆者自作のプリセットが同梱済み)

　音源やスクリプトファイルが増えた時に分かりにくくなるので、新しくフォルダを作り、**音源は「music」**、**スクリプトは「script」**という名前のフォルダの中にまとめようと思います。![6E1651B6-9767-4583-8EBE-4AA7FFD67568.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/d8a4d682-3f70-899e-6548-c38710720293.png)

#スクリプトについて
　音楽やセリフに合わせて顔を動かすためには、「**どんな顔**を**何秒間**表示するか」といった情報を指定するスクリプトファイルが必要ですよね。
　今回は、csvファイルを使ってスクリプトを書きます。(編集時はテキストファイル(.txt)で行い、実行する前にcsvに拡張子を変更するのも可。)
1行で1フレーム(つまり1つの顔)を表しています。

　書き方はある程度決まっているので、まずは写真をご覧ください。
![12AACF5E-8966-4D82-B4C3-132D5AF783BD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/9945cb9e-eb82-a93d-6bc2-4983b98cdf9f.png)

##スクリプトの書き方
例として一番上の行を見てみましょう。

`0,Reye2//Leye2//mouth3,intro,3.2 `

3つの`, `によって4つの領域に分かれています。それぞれの領域にはこんな意味があります。

* **1つ目**:**特に意味はない！！**(~~前言撤回~~)順番調整にでも使ってください。必ず**整数値**を入れてください。(入れないとエラー吐きます)

* **2つ目**:表示する**顔のパーツ**を記入します。予め読み込んであるプリセット(後述)の名前を記入します。`//`で区切ることで複数パーツを追加出来て、順番は不問です。例の場合、Reye2,Leye2,mouth3の3つのパーツが合成されます。![43EF73FD-E9FD-403A-8F06-406009C83BA2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/68658cb6-df08-c3dc-da02-6921c74f8b23.png)
*  **3つ目**:そのフレーム(顔)に**名前**をつけることができます。あとで見返した時に分かり易い名前にしましょう。必ず**英語、数学のみ**で記入してください。(日本語で書くとエラー吐きます。記号も控えましょう。)

* **4つ目**:その顔の**表示時間**です。単位は秒で小数値でもokです。プログラムの特性上、60fpsより大きいのものは表示出来ないので、0.02秒より小さい値にするのは控えましょう。

まとめるとこんな感じ。

**`整数値,プリセット名//プリセット名,名前(英数字),表示時間(秒)`**



スクリプトの間に区切りをつけたり、コメントを入れる時は`< `を使います。
![D47A4999-0179-4FC6-8536-3B56BEBFE79A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/3c5008a7-f64a-656b-79f1-1ca1ee8bb048.jpeg)

**空白の行があるとエラーになるので必ず`〈`を補ってください。**
#プリセット
　スクリプトに色のつくマスを1マスずつ記入することもできますが、非常に見づらくなってしまいますよね。そこで、よく使うパーツを登録しておき、その名前をいくつか書くことで**パーツを合成して、短い文章量でスクリプトが書けるようにしました。**

　配布しているファイルの中には、**筆者が自作したプリセットが既に入っています。**アニメ版、アプリ版のライブシーンの中で登場した顔を全て収録しています。

(口パーツ11種、目のパーツ10種、頬のパーツ2種)(Ver2.8現在)


<details><summary> **用意したプリセットの一覧表はこちら** </summary><div>
　右側の目のみ設定する時はReye●、(●は数学)
　左側の目はLeye●、
両側の目を一括設定する時はeye●と記述します。

![CFBCBA3C-1CC8-4E0F-9D43-45DE52BAE3E3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/436b7364-90fd-528b-b150-6ab6fe317da2.png)
![9A0841F2-4652-4758-BA4F-359A74F89ACB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/92c23538-6f83-3f2f-1f5e-fbec1f21e532.png)

</div></details>

`//`で区切ることで複数パーツを追加出来て、順番は不問です。
以下の例では、Reye2、Leye2、mouth3の3つのプリセットを組み合わせたものです。
`0,Reye2//Leye2//mouth3,intro,3.2 `
![E75D864C-7FE8-4A7A-8C7F-76756E1F9B0C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/410a2ca2-78ee-65b8-3a17-114e8d6dd8d7.png)
↑Boardのスペルミスは許して……


#アニメーションの仕組み
アニメーションのプログラムは以下のような構造になってます。
例えば、再生開始後既に10秒経過した後で、「画面A」を3.2秒間表示、その後「画面B」に切り替えるまでの動きです。
![7091F0BE-2C2C-49CB-A66D-185BA14738CB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967492/88e5450c-6945-32fb-8bc7-1f24bf4f30ee.png)
<details><summary> アニメーションの仕組み</summary> <div>

　「画面A」が表示される瞬間に**始めからの合計時間**が計算(加算)されます(10+3.2)。

毎秒60回自動で実行されるupdate()の中で、**実際の経過時刻を取得**し、**「経過時間」が「合計時間」を上回っているか**をチェックします。下回る時(False)は何も実行せず、画面はそのままです。
　つまり再生開始後10〜13.2秒の間、「画面A」が表示され続けるということになります。
〈例〉
合計時間<=経過時間
13.2<=10(False)
13.2<=10.1 (False)
13.2<=10.2 (False)
……
……
13.2<=12.9(False)
13.2<=13.0 (False)
13.2<=13.1 (False)
13.2<=13.2 (**True！!**次の画面へ進む)

　もし経過時間が13.2秒を過ぎたら、次の画面に進みます。次の画面が表示される瞬間に、また合計時間が加算され(13.2+1.4)、「画面B」は開始後13.2〜14.6秒の間表示されます。
これをずっと繰り返すことでアニメーションが実現します。

　また、上図赤字「誤差」を設定することで、表示タイミングの微調整ができます。次の画面に進む時の表示遅延は端末の能力に左右されるので(筆者の環境では0.02秒)、同じスクリプトを他の端末で使いたい時に便利です。

〈例〉誤差補正を0.2秒と設定した時
合計時間<=経過時間
13.2-0.2<=10(False)
13.2-0.2<=10.1 (False)
13.2-0.2<=10.2 (False)
……
……
13.2-0.2<=12.9(False)
13.2-0.2<=13.0 (**True!!画面遷移開始**)

13.2+1.4-0.2<=13.1 (False、画面遷移中……計算式は画面Bの時間(1.4秒)が足されています。)
13.2+1.4-0.2<=13.2 (False、このあたりで**画面遷移が完了**して欲しい)

　常に**始めから**の時間を計算することで、万が一途中で遅延しても後に響かず、次のフレームで回復できることがわかります。

</div></details>