Silverlightの上でXNAが動作する画面
Silverlight/XNAのベースがSilverlightであるということは、着目すべきはSilverlightの上でXNAが動作している水色の画面(GamePage)です。この画面は「GamePage.xaml」と「GamePage.xaml.cs」から構成されています。これらのファイルを解析することにより、Silverlight/XNAの仕組みを見てみましょう。
「GamePage.xaml」ファイルは、以下のように、ほぼ空のXAMLコードになっています。
<phone:PhoneApplicationPage x:Class="SlXnaApp1.GamePage" …中略…"> <!--完全に XNA Framework を使用してページをレンダリングするため、XAML コンテンツは必要ありません。--> </phone:PhoneApplicationPage>
一方、「GamePage.xaml」のコードビハインドである「GamePage.xaml.cs」ファイルには、以下のようなコードが書かれています。
public partial class GamePage : PhoneApplicationPage { ContentManager contentManager; GameTimer timer; SpriteBatch spriteBatch; public GamePage() { InitializeComponent(); // アプリケーションからコンテンツ マネージャーを取得します contentManager = (Application.Current as App).Content; // このページのタイマーを作成します timer = new GameTimer(); timer.UpdateInterval = TimeSpan.FromTicks(333333); timer.Update += OnUpdate; timer.Draw += OnDraw; } protected override void OnNavigatedTo(NavigationEventArgs e) { // グラフィックス デバイスの共有モードを設定して XNA レンダリングを有効にします SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true); // 新しい SpriteBatch を作成します。これは、テクスチャの描画に使用できます。 spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice); // TODO: ここで this.content を使用してゲーム コンテンツを読み込みます // タイマーを開始します timer.Start(); base.OnNavigatedTo(e); } protected override void OnNavigatedFrom(NavigationEventArgs e) { // タイマーを停止します timer.Stop(); // グラフィックス デバイスの共有モードを設定して XNA レンダリングを無効にします SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false); base.OnNavigatedFrom(e); } private void OnUpdate(object sender, GameTimerEventArgs e) { // TODO: 更新ロジックをここに追加します } private void OnDraw(object sender, GameTimerEventArgs e) { SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: 描画コードをここに追加します } }
それでは、このコードに関して、要点を説明していきましょう。
Silverlightの上でXNAのゲームループを生成する
まずフィールドに着目すると、GameTimerというクラスを定義しています。このクラスこそがSilverlight/XNAにおける要の一つです。
GameTimer timer;
XNAでは、Gameクラスを継承し、そのUpdateメソッドやDrawメソッドをオーバーロードしていましたが、Silverlight/XNAでは、このGameTimerクラスのUpdateイベントやDrawイベントを使ってゲームループ処理を記述します。この際、GameTimer.UpdateIntervalプロパティには、ゲームループの発生間隔を設定できます。
public GamePage() { timer = new GameTimer(); timer.UpdateInterval = TimeSpan.FromTicks(333333); timer.Update += OnUpdate; timer.Draw += OnDraw; }
GameTimerクラスは、PhoneApplicationPage.OnNavigatedTo()メソッド内で開始し、PhoneApplicationPage.OnNavigatedFrom()メソッド内で停止しています。
protected override void OnNavigatedTo(NavigationEventArgs e) { timer.Start(); } protected override void OnNavigatedFrom(NavigationEventArgs e) { timer.Stop(); }
これらはそれぞれ、他画面から自画面に遷移したときと、自画面から他画面に遷移するときに呼ばれるメソッドです。これにより、自画面に遷移したときにゲームループが開始され、他画面に遷移するときにゲームループが停止する仕組みとなっています。