XNAでSilverlightのUIを描画する
UIElementRendererクラスを利用すると、SilverlightのUIをXNAの画像データに変換することが可能となります。これにより、XNAで2D画像を描画するのと同様の方法で、SilverlightのUIをXNAで描画することが可能となります。それでは、「GamePage.xaml.cs」に対してUIElementRendererクラスを実装する手順を以下に記載します。
まずは、UIElementRendererクラスをフィールドに定義します。
UIElementRenderer elementRenderer;
つぎに、コンストラクタ内でPhoneApplicationPage.LayoutUpdatedイベントを登録し、イベントハンドラ内でUIElementRendererクラスを初期化します。このイベントは、Silverlightのビジュアルが変化したときに発生するイベントであり、UIElementRendererクラスは、UIの再描画が必要となったタイミングで再構築する必要があります。この際、UIElementRendererクラスのコンストラクタには、引数としてSilverlightのUI要素とそのサイズを指定します。
public GamePage() { …中略… LayoutUpdated += new EventHandler(GamePage_LayoutUpdated); } private void GamePage_LayoutUpdated(object sender, EventArgs e) { if (elementRenderer != null) { elementRenderer.Dispose(); } elementRenderer = new UIElementRenderer(this, SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Width, SharedGraphicsDeviceManager.Current.GraphicsDevice.Viewport.Height); }
あとは、GameTimer.DrawイベントでUIElementRenderer.Renderer()メソッドを実行し、SpriteBatchクラスを用いてUIElementRenderer.Textureプロパティを描画します。UIElementRenderer.Renderer()メソッドを実行すると、初期化時に指定したSilverlightのUI要素がXNAで描画可能な画像データに変換されて、UIElementRenderer.Textureプロパティに格納される仕組みとなっています。
private void OnDraw(object sender, GameTimerEventArgs e) { …中略… elementRenderer.Render(); spriteBatch.Begin(); spriteBatch.Draw(elementRenderer.Texture, Vector2.Zero, Color.White); spriteBatch.End(); }
これにより、XNAで描画している画面の上に、SilverlightのUIコントロールを重ねて描画することが可能となります。
UIElementRendererとイベントハンドリング
このように、UIElementRendererクラスを利用すれば、同一の画面でSilverlightとXNAを融合させることが可能となります。この際、SilverlightのUIコントロールから発生する各種イベントを利用することも可能です。それでは、UIElementRendererクラスを利用して画面を描画する場合、Silverlightのイベントをどの程度まで利用することができるのでしょうか?
以下の動画では、Silverlight/XNAプロジェクトを新規に作成し、「GamePage.xaml」に「MainPage.xaml」のUIを複製して実行しています。この際、UIElementRendererクラスは利用していません。
このため、当然ながら水色の画面(GamePage)においてSilverlightのUIは描画されません。しかしながら、本来ボタンが表示されるであろう箇所をクリックすると、しっかりとイベントが発生していることが分かります。つまり、SilverlightのUIはあくまで画面に描画されていないだけであり、裏ではしっかりと動作しているのです。
このことからも、UIElementRendererクラスの役割は、SilverlightのUI要素を画像に変換するだけであることがお分かりいただけると思います。よって、UIElementRendererクラスを利用する場合、Silverlightのイベントはすべて利用することが可能であるといえます。