状態をクラスとして表現するもの。
これはゲームプログラムでは定番の処理。タイトル、ゲーム中、ゲームオーバーなどの状態をクラスで表現し、それらを切り替えて使用する。
// 状態を表すインタフェース public interface State { public abstract void proc(Context context); public abstract void draw(Context context); }
// タイトルを表すクラス public class Title implements State { private static Title singleton = new Title(); private Title() { } public static State getInstance() { return singleton; } public void proc(Context context) { // タイトルの処理 ... // STARTボタンが押されたらゲームの状態へ if ( STARTボタン押されたか ) { context.changeState( GameMain.getInstance() ); } } public void draw(Context context) { // タイトル画面の描画 } }
// ゲーム中を表すクラス public class GameMain implements State { private static GameMain singleton = new GameMain(); private GameMain() { } public static State getInstance() { return singleton; } public void proc(Context context) { // ゲーム中の処理 ... // 自機が全部やられたらゲームオーバーへ。 if ( 自機が全部やられた? ) { context.changeState( GameOver.getInstance() ); } } public void draw(Context context) { // ゲーム中画面の描画 } }
// ゲームオーバーを表すクラス public class GameOver implements State { private static GameOver singleton = new GameOver(); private GameOver() { } public static State getInstance() { return singleton; } public void proc(Context context) { // ゲームオーバーの処理 ... // ボタンが押されたらタイトルへ if ( ボタンが押された? ) { context.changeState( Title.getInstance() ); } } public void draw(Context context) { // ゲームオーバー中画面の描画 } }
// コンテキスト、状態を管理するインタフェース public interface Context { public abstract void changeState(State state); }
// ゲーム全体のクラス public class Game implements Context { private State state = Title.getInstance(); // 現在の状態 public void proc() { state.proc(); } public void draw() { state.draw(); } public void changeState(State state) { this.state = state; } }
※ソースはイメージを表したもので、実際にはこのまま入力しても動作しない。
これは非常に単純化した例。タイトル、ゲーム中、ゲームオーバーをStateを継承したクラスで表し、proc()でそれぞれに応じた処理を行い、draw()で描画を行う。
ゲーム全体のクラスではStateがなんであろうとproc()とdraw()を呼べばよい。
ただし、ここに挙げた例だとchangeStateをしたフレームでproc()とdraw()のStateが異なるという問題がある。対処としてはStateをすぐ変更するのではなく、予約しておいて次のフレームで変更するとか。
参考文献:(旧版)Java言語で学ぶデザインパターン入門
参考:ギコ猫とStateパターン
(2007-9-14 ソースで各状態がインタフェースになっていたのをクラスに修正)