赤宿 = Red Inn

素人の試行錯誤と2Dゲームプログラミング

Control

 いかにゲームを動かすかの第一歩。制御の要素を考えていくことで、ゲーム全体の振る舞いを作ってしまう。この世界観、つまりオブジェクト指向のありかたがゲーム制作に非常に有効だと思う。
 素は例によってBob氏のコードより。氏のものはViewとしての面が強かったが、この記事では制御の要素として注目する。

Classes

 Controlの構造は、スタック式のステートマシンと木構造の親子関係を掛け合わせたもの。

Cradle

 Controlの木構造のルートにあたるクラス。(命名は気分による)。

  • controls: 登録(格納)されたControlのリスト。
  • state: 子のスタック(LIFO)。一番上のものをactiveとみなし、更新する。
  • register<T>(T): self.controlsにT: Controlを格納(登録)する。
  • push<T>(): self.controlsの中で型がTのものをスタックに積む。
  • pop<T>(): スタックから一番上のControlを取り出す。
Control

 ゲームの制御要素。

  • children: 子のリスト(オプショナル)。
  • onEnter(), onExit(): ライフサイクル(?)関数。スタート的な面。
  • update(), handleInput(): 同上

 ライフサイクル関数と言っていいのか、Cradleから呼ばれる関数を持つ。親がactiveな子は、ライフサイクル? が伝わり、親によって更新され得る。

Controlによる世界観の具体例(ローグライク)

Controlの親子関係:

  • RoguelikeControl
    • EngineControl
    • PlayerControl
      • DiagonalModeControl
      • DirectionModeControl
    • SequenceControl

各Controlの役割(責務):

 RoguelikeControl: cradle.push(child) により適切な子をactiveにする。
  EngineControl: ゲームmodelの時間を進める。
  PlayerControl: プレイヤ操作の制御をする。
   DiagonalModeControl: コンポーネント。Onなら斜め以外の方向入力をオミットする。
   DirectionModeControl: コンポーネント。Onなら方向入力で移動せず、向きのみの変更にする。
  SequenceControl: エフェクトなど、シーケンシャルな振る舞いを再生する。

 こうして、実に自然にシンプルに、ゲームの振る舞い(制御)を組んでいける。

「ステート」を振り返って

 ゲームの状態を切り替えてゲームを制御するというアイデアはよく聞く。Controlもステートに近いが、考え方が決定的に違うと思う。Controlは、

  • 制御という"もの"を考える( -> 自身の動作を定義していく: 「制御が働く」ニュアンス)
  • 責務は担当範囲を制御すること(controlling) (次行の通り、担当範囲のサイズは自由)
  • 制御を要素の集まりとして捉えやすい (a control may consist of small ones)

 一方、ゲームのステートを考える場合、

  • ある状態を考える (他者の動きを定義していく)
  • 責務はその状態におけるゲーム全体の動作を指示すること (大きい)
  • 制御を動作の集まりとして捉えにくい (Game_State/Mode_Componentの一般的な呼び名が無く、コンポーネントに分ける発想が難しい)

 小さなもの、たとえばキャラの内部状態を切り替えることは理解できる。一方、大きなもの、たとえぼゲーム全体の状態(モード)を考えるのは難しい。責務の範囲が分かりにくい。
 ゲームの状態としてPlayerControlModeを考えると、その責務は、プレイヤ操作時のゲーム全体の振る舞いのように思えるだろう。初めからプレイヤ操作だけを責務にする命名(PlayerControl)がいいと思う。
 また、ゲームの状態を見つけるのは、制御の要素を考えるよりも難しい。制御は、動作するものの方から考え始めることができるが、ステートから考え始めた場合、ゲームの状況から考える必要がある。
 制御の存在を認めると、楽に自然にコードを組んでいけると思う。viva OOP!!

まとめ

 Controlの世界観では、制御の要素を考えていく。ステートオブジェクトは存在せず、アクティブなControlを切り替えることで、ゲームの振る舞いが変わる。Controlの世界観を導入することで、自然な発想でゲームを作ることができるかもしれない。