前回ようやく説明終了したサンプルなんすけど、これだとscript配列の要素を順に表示して、最後に絵を表示しておしまいの一本調子なんすよ。

 そうじゃなくて、複数の絵を用意して、進行状況に合わせて切り替えるにはどうするか?

 そういう場合、決まった脚本に従って、物語を進行させる仕組みが必要っす。

 でないと、話の展開を変えるたびにプログラム変更ってことになるからね。

 デスマーチになるから…、マジで。

 

 こういう仕組みは、ノベルゲーム/アドベンチャーゲームなんかではスクリプトエンジンって呼ばれてます。吉里吉里2NScripter2なんかが有名。どっちもWindows用だけど、探せばiPhone用もあるんじゃないだろうか。

 UnityCocos2DRPGツクールなんかはゲームエンジンと呼ばれてて、もう一段、自由な動作が定義できるようになってます。そのぶん作るときの複雑さも増すわけですわ。でも、こっちは一旦プロジェクトを作ると、そこからiPhone用プロジェクトやWindows用プロジェクト、Android用プロジェクトを作り出してくれるようになってるんで、いろいろなハードに向けてゲームアプリ作りたいってのなら、チャレンジして見る価値はあります。

 もっと原始的なものとしては、luaってのがMITライセンスで配布されてて有名(例えばNScripter2なんかが組み込んでるみたい)で、独自にエンジン作りたいとか思ってる人は検討してみましょう。

 ちなみに、ここで言う原始的なってのは、単純と言う意味ではなく、アプリのプログラム構成群の中でよりハードに近いプログラムって意味です。

 

 

 この分類だと、スクリプトエンジンやゲームエンジン、luaなんてのはミドルウエアて層に分類されます。

 で、私らがアプリ作るために使ってるUIViewやUIViewControllerなんかを提供してるUIKitはフレームワークとも呼ばれ、OSの一部として分類されますです。

 こいつが一番ハードに近い。

 

ラノベ本の原型から抜粋(41ページ〜部分に相当)


 OS(オーエス)とはOperating System(オペレーティング・システム)の略称だ。ハードの性能を引き出すための操作(オペレーティング)を担当するソ フトの組み合わせ(システム)で、個々のアプリを1つのハード上で仲違いさ せずに運用する役割も果たしている。 アプリの元締め的な存在のソフト。 

 

 

 ちなみにアプリという呼び名は、このOSが提供する機能を応用 (Application:アプリケーション)するソフトという意味からきている。

 さっきの映画の例でいえば、5.1ch音響システムとか、3D立体視システム といったものがOSが提供する機能に相当し、その特性を利用するように作られた映画がアプリに相当する。 このようにソフトには、OSとアプリという階級があり、Windowsは、このOSと呼ばれる階級のソフトとなる。Macの場合はmacOS、iPhoneやiPad ではiOSと呼ばれるソフトがOSに該当する。 映画が映画館に配布されるときに、同じ映画でも、3D立体視システム用 とそうでないもの用に別れるように、アプリもWindows、Mac、Android、 iPhoneといったOS別に用意する必要がある点も同じだ。 


 

 てなわけです。

 説明ついでに以後はiPhoneやiPadのアプリをiOSアプリって呼ぶようにします。

 

 luaはC言語で書いたプログラムから呼び出して使うようになってるんだけど、XcodeはSwiftとObjective-Cを混在して使えるようになってるんで、組み込めると思われ。やってみたいと思う人は「swift lua」あたりで検索するべし。

 

 ま、そんな本格的なものじゃないけど、scriptを文字列の配列じゃなく、辞書の配列にすれば、ただの文字列よりは融通のきく、スクリプトエンジンっぽいのが作れるんすよ。

 例えば、タップで進む、次みたいな画面進行をしたいならどうするか?

 


主人公:誰だ?

 #須瀬の画像がフェードイン

主人公:「須瀬」?

主人公:なんだ、お前も寝坊か?

須瀬:何をのんきな・・・

須瀬:あんたらしいけど

主人公:何が?

須瀬:何でもない

主人公:?

須瀬:まあ、どのみち、もう意味ないしね

主人公:?

須瀬:そうだ。あんた最近、平坂のおじさんと話した?

主人公:いや、でも何で平坂のおじさん?

須瀬:別に、話してないならいい

 #須瀬理子の画像がフェードアウト

主人公:なんだあいつ。急に平坂のおじさんとか

主人公:なんだか学校行く気なくなっちまったな…

主人公:帰るか

 #背景画面フェードアウト

 効果音:歩行音開始

主人公:歩きながら、半年前のことを思い出していた

主人公:嫌な思い出

主人公:幼馴染だった女の子が死んだ日

主人公:平坂なみの葬式で、須瀬は泣いていた

主人公:あの日以来、おじさんとは話してない

主人公:須瀬がクラスの中で浮き始めたのも、あの日からだったな

 効果音:歩行音停止

主人公:平坂、お前がいなくなって須瀬がグレちゃったよ

主人公:玄関前には、死んだはずの平坂なぎが立っていた

 #家の玄関背景&平坂なぎの画像フェードイン


 

 こんなシーンを作りたいなら、まず文章を、主体や行動、対象で分類しちゃうんですな。

 

 主体:主人公、須瀬、平坂、背景、前景

 行動:喋る、考える、フェードインする、フェードアウトする

 対象:道の画像、玄関の画像、須瀬の画像、平坂の画像

 

で、この分類をキーワードにして辞書を作っちゃうわけです。例えば

 

 主人公:誰だ?

 

なら

 

 [

  "主体" : "主人公",

  "行動" : "喋る",

  "対象" : "誰だ?"

 ]

 

という辞書にしちゃう。

 辞書の簡易表記がわからん人は「アンラップしてチン♪」を読むように。

 これが、もし

 

 #須瀬理子の画像がフェードイン

 
なら
 

 [

  "主体" : "前景",

  "行動" : "フェードインする",

  "対象" : "須瀬の画像"

 ]

 
 もしくは

 

 [

  "主体" : "須瀬の画像",

  "行動" : "フェードインする",

  "対象" : "前景"

 ]

 

といった具合っす。
 で、この各辞書を配列scriptに要素として格納しておき、tapメソッドで読み出して、"主体"、"行動"、"対象"を元に処理を実行する。
 
 これを実際に書いたのが以下のサンプルっす。
 scriptから一個ずつ取り出した辞書をexecute(action:)メソッドで解釈して動作させてるわけやね。
class ViewController: UIViewController {
   ・・・
    let script : [ [String:Any] ]  = [
        ["主体" : "主人公","行動" : "喋る","対象" : "雨の日はだるい…"],
        ["主体" : "主人公","行動" : "喋る","対象" : "今日は学校休んじゃおっかな〜"],
        ["主体" : "主人公","行動" : "喋る","対象" : "誰だ"],
        ["主体" : "前景","行動" : "フェードイン","対象" : "girl"],
        ["主体" : "主人公","行動" : "喋る","対象" : "「須瀬」?"],
        ["主体" : "主人公","行動" : "喋る","対象" : "なんだ、お前も寝坊か?"],
        ["主体" : "須瀬","行動" : "喋る","対象" : "何をのんきな・・・"],
        ["主体" : "須瀬","行動" : "喋る","対象" : "あんたらしいけど"],
    ・・・
    func tap() {
        if scriptIndex < script.count {
            execute(action:script[scriptIndex])
            scriptIndex += 1
        }
    }
    ・・・
    func execute(action: [String : Any]) {
    ・・・
    }
 
サンプル:
 
 実行すると、タップして話が進んでいくノベルゲームっぽい動きをします。
 
 execute(action:)メソッドや、その中で呼び出されるメソッドでは、switch文や、Bundle、AVAudioPlayerなんて、知らないクラスも出てきますが、ヘルプや検索でなんとかなると思うし、その他はこれまでの解説でわかるものばかりなんで、我と思わん方は、一つ、力試しに何やってるか解析してみてください。
 詳細は次回!
AD