さくらんぼのlambda日記

lambdaちっくなことからゲーム開発までいろいろ書きます。

ゲームに使える状態遷移マシン

備忘録的に吸闘紀で採用している状態遷移マシンの設計と実装について書いておきます。

ゲームに必要な状態遷移マシン

ゲームに使える状態遷移マシン。そこまで複雑な状態遷移マシンは必要とはなりません。
簡単に要件をまとめておきます。

まず、各遷移する状態を表す状態は以下の要件があれば十分です

  • 各状態は特定のタイミングで指定した関数を実行する
  • 各状態が定めている関数の引数の数や意味はそれぞれに異なる可能性がある

次に、上記の状態を管理し、遷移を適切に処理する状態遷移マシンクラスの要件です。

  • 状態遷移マシンは状態を2種類もつ

各要件の詳細

各状態は特定のタイミングで関数を実行する

以下の3つのタイミングで、各状態ごとに定義されている関数を実行する必要があります。

  • 状態に遷移する時に実行する関数(enter)
  • 状態の更新関数(update)
  • 次状態に遷移する時に実行する関数(leave)

f:id:sakura-1:20110524171252p:image:w400

各状態が定めている関数の引数の数や意味はそれぞれに異なる可能性がある

上記の関数の引数は、各状態ごとに異なる可能性があります。
これは、敵の更新関数、プレイヤーの更新関数、シーンの更新関数では必要な情報が異なる場合が少なくないためです。

状態遷移マシンは状態を2種類もつ

ゲームでは基本的な状態に加えて、すべての状態に関係する常に気にしなければならない状態があります。

例えば、吸闘紀ですと基本的な状態としては、歩く、ジャンプするなどが有ります。これとは別に、物を吸い込んでいる状態とそうでない状態があります。この後者の物を吸い込んでいる状態などは全ての状態に影響を与えます。物を吸い込んでいる状態では、空は飛べないとか、吸い込んでいない状態では物をすこむことが出来る等...。
f:id:sakura-1:20110524171251p:image:w400

クラス分けをしてみる

というわけで、これらの要件を満たせるようなクラス構成を考えてみます。
こんな感じだとうまくいくはず。ざっくりUMLを書いてみました。

f:id:sakura-1:20110524134152p:image

使用上の注意

この設計では、各エンティティが自分の状態を管理する状態遷移マシンを持っています。また、状態遷移マシンは各エンティティへの参照を持っています。
このため、相互に所有している関係となっています。
エンティティが開放されると同時に状態遷移マシンも開放されるように、状態遷移マシンの参照はエンティティ内部に閉じるようにしておく必要があります。

実装

次回にまとめてソースは書きます。