Windowsストア アプリ 作り方解説 XNA編 第4回 ~キャラクターの描画~

マイクロソフトの田中達彦です。
本連載では、Windows Phone 7用のXNAで開発したShoot EvoというゲームをWindowsストア アプリとして移植したときのポイントを紹介します。
本連載では、C#とXAMLを使用して同様のアプリを作っていきます。

[XNAの描画方法]
XNAとC#/XAMLで全く違う部分が、キャラクターなどの画像の描画の部分です。
XNAでは、例えばボールを描画するときには以下のようにBallというTexture2Dのフィールドを作成します。

Texture2D Ball;

そして、Loadメソッドでball.pngという画像を以下のように読み込み、Ballフィールドに代入します。

Ball = Content.Load<Texture2D>("ball");

描画は、Drawメソッドで行います。
以下のように、描画するものと位置、色を指定して描画します。

spriteBatch.Draw(Ball, BallLocation, Color.White);

BallLocationはVector2で定義されたフィールドで、描画する位置のX座標をY座標を含んでいます。

[C#/XAMLでの描画方法]
C#/XAMLの場合は、XAMLに画像イメージを表示させるためのImageコントロールを用意し、そのパラメーターを変えることで目的の画像を表示させます。
まずXAMLには、以下のようにImageコントロールを貼り付けます。

<Image x:Name="ball1" HorizontalAlignment="Left" Height="60" Margin="338,403,0,0" VerticalAlignment="Top" Width="60" Source="Assets/ball.png" Stretch="Fill"/>

このときのMarginの値はボールの位置です。
この値はプログラム中で変更していきます。
もしプログラム中で画像データを読み込むときは、以下のようなコードを書きます。
初期値として設定している画像以外の画像を表示させるときに使います。

string imageUri = "ms-appx:///Assets/ball.png";
BitmapImage bitmap = new BitmapImage(new Uri(imageUri));
ball1.Source = bitmap;

Drawメソッドに相当する部分では、表示する位置のみを以下のように設定します。
ImageコントロールにはMarginというプロパティがあり、そこで位置を決めます。
Pointとして定義したBallLocationを使い、ball1というImageコントロールの位置を定義しています。

ball1.Margin = new Thickness(BallLocation.X, BallLocation.Y, 0, 0);

[XAMLでの画面構成]
C#/XAML版では、サッカーのフィールド(芝生の部分)、サッカーゴール、ボール、モンスターの4つの要素にそれぞれImageコントロールを使って画像を表示させています。
以下は、そのときのXAMLのコードの例です。
プロジェクト名や、画像を貼り付ける位置によって細かいパラメーターが変わることがあります。

<Page
    x:Class="App33_xnafake.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App33_xnafake"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" PointerPressed="Page_PointerPressed_1" PointerReleased="Page_PointerReleased_1" SizeChanged="Page_SizeChanged_1">

<Grid x:Name="grid1" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" >
        <Grid x:Name="fieldGrid" RenderTransformOrigin="0,0" Margin="120, 140, 0, 0">
            <Grid.RenderTransform>
                <CompositeTransform x:Name="fieldScale1" ScaleX="1" ScaleY="1"/>
            </Grid.RenderTransform>
            <Rectangle x:Name="field1" Fill="Green" HorizontalAlignment="Left" Height="580" Stroke="Black" VerticalAlignment="Top" Width="400"/>
            <Image x:Name="goal1" HorizontalAlignment="Left" Height="150" Margin="0,0,0,0" VerticalAlignment="Top" Width="400" Stretch="Fill" Source="Assets/goal.png"/>
            <Image x:Name="monster1" HorizontalAlignment="Left" Height="160" Margin="123,248,0,0" VerticalAlignment="Top" Width="160" Source="Assets/monster.png" Stretch="Fill"/>
            <Image x:Name="ball1" HorizontalAlignment="Left" Height="60" Margin="338,403,0,0" VerticalAlignment="Top" Width="60" Source="Assets/ball.png" Stretch="Fill"/>
        </Grid>
    </Grid>
</Page>

grid1という名前のGridの中に、fieldGridという名前のGridがあります。
Windowsストア アプリはさまざまな解像度に対応しないといけないため、fieldGridというGridを配置し、そのGridを拡大/縮小させられるようにしておきます。
fieldGridは後の記事で説明します。

[前後の記事]
第3回 : Update、Drawメソッドを置き換える
第5回 : ジェスチャーのシミュレート
番外1 : Shoot Evo リリース1を公開
番外2 : Shoot Evoのソースコード / プロジェクト ファイルを公開

マイクロソフト
田中達彦