WisdomSoft - for your serial experiences.

スプライトの伸縮

テクスチャの本来のサイズとは別に、任意のサイズに伸縮して描画できます。

長方形領域に合わせて伸縮

前述した Draw() メソッドは、指定した座標からテクスチャ本来のサイズで描画しましたが、オーバーロードされている別の Draw() メソッドを使い、テクスチャを特定のサイズに伸縮して描画することもできます。スプライトをテクスチャ本来のサイズとは別に伸縮して描画するには、Vector2 オブジェクトの代わりに、スプライトの長方形領域を表す Rectangle オブジェクトを受け取る Draw() メソッドを使います。

SpriteBatch クラス Draw() メソッド
public void Draw (
         Texture2D texture,
         Rectangle destinationRectangle,
         Color color
)

destinationRectangle パラメータには、スプライトを描画する長方形領域を表す Rectangle オブジェクトを渡します。このメソッドは、texture パラメータに指定したテクスチャを destinationRectangle パラメータに渡した長方形領域に収まるように伸縮して描画します。それ以外は、前述した Draw() メソッドと同じです。

画像の伸縮は描画時に行われるため、事前に伸縮した画像ファイルを用意して描画した方が効率的です。Draw() メソッドで伸縮したスプライトを表示するのは、事前に用意できないアニメーションなどの動的な伸縮処理を行うような場合でしょう。

コード1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

public class TestGame : Game
{
    public static void Main(string[] args)
    {
        using (Game game = new TestGame()) game.Run();
    }

    private GraphicsDeviceManager graphicsDeviceManager;
    private SpriteBatch sprite;
    private Texture2D texture;
    private Rectangle destinationRectangle;

    public TestGame()
    {
        graphicsDeviceManager = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        destinationRectangle = new Rectangle(0, 0, 400, 200);
    }

    protected override void LoadContent()
    {
        sprite = new SpriteBatch(GraphicsDevice);
        texture = Content.Load<Texture2D>("TestImage");
        base.LoadContent();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.White);

        sprite.Begin();
        sprite.Draw(texture, destinationRectangle, Color.White);
        sprite.End();

        base.Draw(gameTime);
    }
}
実行結果
コード1 実行結果

コード1は、Rectangle オブジェクトを受け取る Draw() メソッドを使って、指定した長方形領域にスプライトを伸縮して描画しています。実行結果をみると、描画されているスプライトが元の画像ファイルのサイズと異なっていることが確認できます。

テクスチャのサイズ

ゲームでは、その性質から開発者がコンパイル時に予期していない画像や音楽などのリソースを扱うことは滅多にありません。よって、使用する画像のサイズなどはコンパイル時に確定できますが、それでもテクスチャの制御で幅や高さをソースコードに定数で記述するべきではありません。画像ファイルのサイズを変更したり、他の画像ファイルでも同じロジックを応用するような場合に障害となります。

読み込んだ画像の幅や高さを取得するには、画像ファイルから生成された Texture2D オブジェクトのプロパティを使います。テクスチャの幅は Width プロパティ、高さは Height プロパティから取得できます。

Texture2D クラス Width プロパティ
public int Width { get; }
Texture2D クラス Hieght プロパティ
public int Height { get; }

これらのプロパティは、テクスチャの幅と高さをピクセル単位で返します。元のテクスチャのサイズを参考に配置や伸縮したい場合などで応用できます。 

コード2
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

public class TestGame : Game
{
    public static void Main(string[] args)
    {
        using (Game game = new TestGame()) game.Run();
    }

    private GraphicsDeviceManager graphicsDeviceManager;
    private SpriteBatch sprite;
    private Texture2D texture;
    private Rectangle destinationRectangle;

    public TestGame()
    {
        graphicsDeviceManager = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void LoadContent()
    {
        sprite = new SpriteBatch(GraphicsDevice);
        texture = Content.Load<Texture2D>("TestImage");

        destinationRectangle = new Rectangle(0, 0, texture.Width / 2, texture.Height / 2);

        base.LoadContent();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.White);

        sprite.Begin();
        sprite.Draw(texture, destinationRectangle, Color.White);
        sprite.End();

        base.Draw(gameTime);
    }
}
実行結果
コード2 実行結果

コード2は、Debug クラスの WriteLine() メソッドを使って読み込んだテクスチャの幅と高さを出力します。出力結果を見れば、テクスチャの幅と高さをピクセル単位の値で取得できていることが確認できます。加えて、このプログラムは、常にテクスチャ本来の半分のサイズでスプライトを描画しています。実行時に取得した幅と高さから描画する領域を設定しているため、画像を差し替えても常に半分のサイズで描画します。