2010年11月03日

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

前回のエントリーからだいぶ期間が空いてしまいましたね。

さて、前回の続きを何事もなかったかのように説明していきます。

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

さて、SceneBaseクラスの更新関数ですが、
ここでは画面遷移中の処理を実装していきます。


this.isOtherSceneFocus = otherScreenHasFocus;

まずは自身のシーンフォーカスがあるかどうかのBOOL型を保持します。
引数で指定されてきたものを自身で取得するだけです。

// 画面が完全に消去される場合
   if (isExiting == true)
   {
    // まずTransitionOFF状態にする
    sceneState = SceneState.TransitionOff;
    if (UpdateTransition(gameTime, transitionOffTime, 1) == false)
    {
     // 移行が完全に終了した場合、SceneManagerから削除される
     GameManagerRef.RemoveScene(this);
    }
   }

自身の画面が終了フラグがTRUEの場合、トランスレーションOFFに状態を設定します。
ここでUpdateTransition関数が呼ばれていますが、後で説明いたします。
内容は画面遷移の処理とだけ
画面遷移処理が完了した場合、RemoveSceneが呼ばれ、自身のシーンはスタックから削除されます。

// 画面が他の画面に覆われる場合
   else if (coveredByOtherScreen == true)
   {
    if (UpdateTransition(gameTime, transitionOffTime, 1) == true)
    {
     // TransitionOFF状態
     sceneState = SceneState.TransitionOff;
    }
    else
    {
     // 移行が完了したので画面を隠蔽する
     sceneState = SceneState.Hidden;
    }
   }
続いて他の画面に覆われている状態の場合、
終了はしないんだが、他の画面が前にあるため、自身を非表示にするための処理となります。
ここでもUpdateTransition関数が呼ばれています。
画面移行中はTransitionOFF状態。移行完了するとHidden状態となります。

// OFFに移行でない場合
   else
   {
    // On状態へ移行する
    if (UpdateTransition(gameTime, transitionOnTime, -1) == true)
    {
     // TransitionON状態
     sceneState = SceneState.TransitionOn;
    }
    else
    {
     // 移行完了したので、ON状態
     sceneState = SceneState.Active;
    }
   }
上記二つの状態に該当しない場合、このシーンはアクティブ状態またはアクティブ準備中状態です。

UpdateTransition関数の結果により状態をわけます。
移行中の場合、TransitionON状態とし、
移行完了して自身がアクティブになれば、Active状態に設定します。

更新関数内はこれだけです。
あくまでBaseの処理となるため、各シーンの処理は各継承したソース内で行います。
そして各シーンからこの基本となるUpdate関数を呼ぶっということで
画面移行の手続きなどを行うことができるという流れとなります。

bool UpdateTransition(GameTime gameTime, TimeSpan time, int direction)
  {
  }
さて次にさきほどUpdate関数内にて複数回登場した関数を実装します。
この関数では、シーンが移行中であるか完了したかを判断する処理となります。

   float transitionDelta;

   if (time == TimeSpan.Zero){
    transitionDelta = 1;
   }
   else{
    transitionDelta = (float)(gameTime.ElapsedGameTime.TotalMilliseconds / time.TotalMilliseconds);
   }

まずは引数で指定された移行完了までの秒数から移行位置を算出します。
Zeroの場合は即完了位置となるため1が設定されます。
Zero以外の場合は、gameTimeから移行完了タイムとの計算にて現在の移行位置を算出します。
ElapsedGameTime→前回の更新から経過したゲーム時間の合計っとMSDNでは明記されています。

   // 移行位置を更新します。
   transitoinPos += transitionDelta * direction;

   // 移行の最後に到達したか
   if (((direction < 0) && (transitoinPos <= 0)) ||
    ((direction > 0) && (transitoinPos >= 1)))
   {
    transitoinPos = MathHelper.Clamp(transitoinPos, 0, 1);
    return false;
   }

   // transitoinPos に到達していない場合、まだ移行が行われている。
   return true;

引数で指定したdirectionを掛け合わせることで-1<0<1の値を完成させます。
これにより、Activeへの移行の場合、transitionPosが0を下回ったか
Hiddenまたは削除される場合、transitionPosが1を上回ったかで移行完了となります。
ちなみに transitoinPos = 1.0f; っとプロパティを設定する際に書いていたように
1でOFF状態、0で完全ON状態となります。
なぜならば、この値がAlpha値の計算に使用されるからです。

  public void ExitScreen()
  {
   if (TransitionOffTime == TimeSpan.Zero)
   {
    // 画面の移行時間がゼロに設定されている場合は、すぐに削除されます。
    GameManagerRef.RemoveScene(this);
   }
   else
   {
    // それ以外の場合、オフに移行してから終了するようにフラグを設定します。
    isExiting = true;
   }
  }
最後は画面が終了するときの準備関数を作成します。
TransitionTimeが設定されていない場合、即削除されます。
値が設定されていると先ほどのUpdate関数を何回か通ることになり、
UpdateTransitionにて移行完了となるとシーンが削除されます。

これでSceneBaseの作成は完了となります。


次はこのSceneBaseを操作するSceneManagerを作成していきますよ〜


XNAをはじめる方へ
XNAゲームプロ...

XNAゲームプロ...

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


XNAの基本的なゲームコーディングなどは上記の書籍で十分学ぶことができます。
私もこの本は初心者におすすめだと感じます。
リファレンス本とまではいきませんが、参考になると思います。




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

メールアドレス:

ホームページアドレス:

コメント:

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


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

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