Push: Ctrl+Y

 技術で遊んで ときどき進む

アプリ ゲームAI

Kotlin × ゲームAI(ステート駆動エージェント)②:グローバルステート

2016/09/15

前回は「獲物を発見したら焼く」とか「焼き終わったら食べる」とか、特定の状態からの遷移部分を作りました。今回は、どのステートにいても発生し得る状態を追加する方法を学んでいきます。

ふいに欠伸したくなったとかそんな感じで、欠伸し終えたら欠伸前の動作に戻って続く感じです。

方針としては

  1. 全部のStateに条件分岐を加える
  2. updateごとに実行されるグローバルステートを追加する

の2通りがありますが、もちろん2の方が今後の追加コストも少なく汎用性も高いのでこっちで実装していきましょう。方針としては、今までFoxがStateを持っていたのをStateMachineを持つように変更する形になります。Stateの処理をStateMachineとしてカプセル化し、より柔軟に変更していけるようにするイメージです。

 

実装

というわけで、さっそく新規クラス:StateMachineを作成していきたいと思います。

 

StateMachineクラスで状態に関するデータ・処理をカプセル化

Null安全なKotlinですが、Javaだとif( m_pGlobalState != null )とかやらなければいけないところを、

  • 型を宣言するときにnull可にする(State<T>?の?がnull可の印)
  • nullじゃなければ実行する、という印に処理前に?をつける

というたった2ステップでさらりといけちゃうのがほんとに素敵!

そしてさらっと出てきたのがジェネリック・・!もちろんこれに合わせてStateやその下位クラスも変更しなければならないわけです。はい、やっちゃいましょう。

 

Stateを総称型(ジェネリクス)にする

ともあれソースから。<T>がおなじみの総称型ですね。

これでFox以外のキャラが出てきても使い回しできるし、かなり幸せな感じになってきたと思います!下位の実装クラスはこんな感じです。

※entity_type.getFsm()については次ででてきます。

 

FoxをStateMachineに対応

FoxからStateMachineに移譲したりしたところもあるので、そっちを修正していきます。

 

ちょっとじゃない修正・・

で、、実は前回もちょっとごまかしていたところがあったのでそこを改修します。changeState()が走ったときexit()からのenter()を一気にやっているので、exit()の変更がenter()で上書きされて、結果的にexit()丸無視になってしまいます。

メッセージをセットして画面表示を変更する部分をFoxで行う

これがうまくいくように改修していきましょう。今までFoxにメッセージを持たせMainActivityのループ内でそのメッセージの表示変更、という2段構えの処理をしていたのを、Foxからメッセージ変更の処理を直接呼べるように変更します。

まず、MainActivityからです。

こんな感じでFoxにUIのメッセージ設定のfunctionを渡し、内部でメッセージ変更できるようにします。(itはKotlinの予約語。高階層関数やラムダ式で検索すると、この書き方についてはいろいろ出てくる。)さらにそのFoxを修正します。

 

1回のループで1メッセージ変更

次に、1回のループで複数回メッセージ変更しないように修正します。最初に書いたように、Androidの仕様に合わせる対応です。

StateMachineを修正します。これはちょっと修正箇所が多いのと、なんかエレガントな回答になっていない気がするので、おいおい検討したいかも。。

ステートが変更になったとき、前のステートのexit処理が終了したらいったんループを抜け、次のループ時に新しいステートのenter処理が走るように修正しています。

 

グローバルステートを実装

もうここまでくれば簡単にできちゃいます!グローバルステートを新しく作りましょう。

で、このグローバルステートをFoxにセットします。

これでときどきあくびするキツネが誕生しました。ちょっとした違いですが、なんかキャラクターっぽい動作になります!

 

まとめ

次回いよいよ他のキャラ登場して通信させる感じになります!Kotlinなかなか書きやすくていいなあ。。

 

-アプリ, ゲームAI
-, ,

おすすめの記事

1
React + Redux入門① - Reduxの概念を理解

React+Reduxでサイトを作っているので、復習がてら「検索画面を作成する」 ...

2
React + Redux + D3.js アニメーション:ドラッグ&ドロップでキングスライムを作った

はい、今回は要素のドラッグ&ドロップを中心に作ってみました。 Mater ...