2010年10月16日

【プログラム】XNAでゲームを作る【シーン管理1】

iPhoneの開発も一通り落ち着いたので、久々にXNAの記事でも…

アクセスログを見てると、XNAでシーン管理というキーワードで検索してくる方が少なからずいらっしゃるので
少しずつ解説していこうかと思います。

といってもXNAデベロッパーサイトのサンプルソースをそのまま流用して使用しているので、
日本語コメント版をDLされてから見るといいかもしれません。

XNAゲームプログラミング

XNAゲームプログラミング

価格:3,654円(税込、送料別)


1回目の今回は各シーン画面のベースとなるクラスを作成しましょう。
タイトル画面やオプション画面、ゲーム画面などすべての画面の基本クラスなのでしっかり理解していきましょう。

新しくCSファイルを作成し、SceneDataとします。
できたCSファイルのクラス定義を以下のようにします。

public abstract class SceneData
{
}

abstractで抽象クラスとして定義しますよ。

その前にそのシーンがどういう状態であるかを定義しておきましょう

// シーン列挙体
 public enum SceneState
 {
  TransitionOn = 0, // 画面表示準備中
  Active,    // 画面表示
  TransitionOff,  // 画面非表示準備中
  Hidden,    // 画面非表示  
 }

public abstract class SceneData
{
}

こんな感じでenumで定義しておきましょう。
これにより表示している画面のステータスを設定、取得する値を設定しました。

ではSceneDataの中身を定義していきましょう。
変数を定義して、プロパティをセットで作成していきます。

// ポップアップフラグ
  private bool isPopUp = false;
  // 現在の画面の上に小画面が表示されるなどの状態を示すフラグ
  public bool IsPopUp
  {
   protected set { this.isPopUp = value; }
   get { return this.isPopUp; }
  }

ポーズメニューなど現在の画面の上に小画面がでているかのフラグ情報を作成します


// 画面をアクティブにするまでの時間
  private TimeSpan transitionOnTime = TimeSpan.Zero;

  public TimeSpan TransitionOnTime
  {
   protected set { this.transitionOnTime = value; }
   get { return this.transitionOnTime; }
  }

// 画面を非アクティブにするまでの時間
  private TimeSpan transitionOffTime = TimeSpan.Zero;

  public TimeSpan TransitionOffTime
  {
   protected set { this.transitionOffTime = value; }
   get { return this.transitionOffTime; }
  }

現在の画面を表示、非表示に切り替える際に必要とする時間を設定します。


// 0(完全にONに移行完了)〜1(完全にOFFに移項完了)までの現在位置
  private float transitoinPos = 1.0f;

  public float TransitionPos
  {
   protected set { this.transitoinPos = value; }
   get { return this.transitoinPos; }
  }

表示、非表示に切り替わる際、現在の状況を示します。
後に更新関数内で使用するので定義段階では深く考えなくていいです。

// 255(完全にON)〜0(完全にOFF)までのアルファ値
  public byte TransitionAlpha
  {
   get{return (byte)(255 - transitoinPos * 255);}
  }

画面切り替えの際のアルファ値を返します。
設定プロパティは存在しないのでReadOnlyとなりますね。

// 現在のシーン状態
  private SceneState sceneState = SceneState.TransitionOn;
  public SceneState SceneState
  {
   protected set { this.sceneState = value; }
   get { return this.sceneState; }
  }

現在のシーン状態です。
最初に定義した列挙体の中の値が設定、返されます。

// 画面移行終了後、削除するか
  private bool isExiting;
  public bool IsExiting
  {
   protected internal set { this.isExiting = value; }
   get { return this.isExiting; }
  }

ゲーム→タイトル画面といった完全にシーンが切り替わる場合か
ゲーム→ポーズ画面といったゲーム画面は生きつつ、他の画面に切り替わるかっという状態を設定、返します。

// 画面がアクティブであり、入力フォーカスがあるか
  private bool isOtherSceneFocus;
  public bool IsActive
  {
   get
   {
    return ( (!isOtherSceneFocus)
     && (sceneState == SceneState.TransitionOn
       || sceneState == SceneState.Active) );
   }
  }

現在、自分自身の画面がアクティブとなっているかを取得します。
これはReadOnlyです

// シーンマネージャクラスアクセス変数
  private SceneManager sceneManagerRef;
  public SceneManager SceneManagerRef
  {
   internal set { this.sceneManagerRef = value; }
   get { return this.sceneManagerRef; }
  }

次回作成予定のシーンマネージャクラスへのアクセス用のプロパティとなります。

// コントローラーID
  // null → 全てのコントローラから制御可能
  // null以外 → 特定のIndexのコントローラのみ制御可能
  private PlayerIndex? playerIdx;
  public PlayerIndex? ControllerIndex
  {
   internal set { this.playerIdx = value; }
   get { return this.playerIdx; }
  }

プレイヤーIDを取得、設定する部分です。
複数プレイヤーを操作するゲームでは重要な機構ですね。

// 各ゲーム画面抽象関数
  public virtual void LoadContent() { }
  public virtual void UnloadContent() { }
  public virtual void HandleInput(InputState inputState) { }
  public virtual void Draw(GameTime gameTime) { }

さて、ここから抽象関数を設定していきます。
まずは上記の関数を定義しておきましょう。

LoadContent
 → Contentに設定したデータを読み込むための抽象関数です。画像データなどその画面に必要なデータはここですべて取得します。

UnloadContent
 → 移行完了後、IsExitingにて画面が破棄される際、その画面でLoadContentしたデータをメモリから削除します。
    メモリを開放する処理となるのでしっかりと処理しておきましょう。

HandleInput
 → メニュー画面などで入力された情報をイベントとして登録するための抽象関数です。
    実際にメニュー画面の作成入るときに詳しく

Draw
 → 描画する抽象関数です。

public virtual void Update(GameTime gameTime, bool otherScreenHasFocus,
               bool coveredByOtherScreen)
{
}

さて、Update関数は中身を実装していきます。

ここがシーン管理の重要な移行処理になるので
次回解説していきます



ラベル:XNA C# シーン管理
posted by ヒイロ at 10:28| 福岡 ☀| Comment(0) | TrackBack(0) | プログラム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。