WisdomSoft - for your serial experiences.

回転や反転

画像から読み込んだテクスチャを回転させたり、水平方向や垂直方向に反転させて描画します。

スプライトの回転

スプライトに回転を加えたい場合は、最も多くのパラメータを持つ Draw() メソッドを使わなければなりません。これらのメソッドは、テクスチャの切り抜き、伸縮、回転、原点の設定などの設定を行うことができます。指定しなければならないパラメータは多くありますが、個々のパラメータは複雑なものではありません。

SpriteBatch クラス Draw() メソッド
public void Draw (
         Texture2D texture,
         Vector2 position,
         Nullable<Rectangle> sourceRectangle,
         Color color,
         float rotation,
         Vector2 origin,
         float scale,
         SpriteEffects effects,
         float layerDepth
)
public void Draw (
         Texture2D texture,
         Vector2 position,
         Nullable<Rectangle> sourceRectangle,
         Color color,
         float rotation,
         Vector2 origin,
         Vector2 scale,
         SpriteEffects effects,
         float layerDepth
)
public void Draw (
         Texture2D texture,
         Rectangle destinationRectangle,
         Nullable<Rectangle> sourceRectangle,
         Color color,
         float rotation,
         Vector2 origin,
         SpriteEffects effects,
         float layerDepth
)

第 2 パラメータが Vector2 型か Rectangle 型かで、大きく分かれます。第 2 パラメータが Vector2 型の場合、テクスチャの伸縮率を scale パラメータで指定しますが、Rectangle 型の場合は scale パラメータは存在しません。それ以外のパラメータは、共通しています。

スプライトの回転は rotation パラメータにラジアン単位を指定します。続く origin パラメータには、スプライトの原点となる座標を指定します。デフォルトでは、左上端 (0, 0) が原点となっていました。scale パラメータには、スプライトの伸縮比率を指定します。この値は、ピクセル単位ではなく、1 をオリジナルのサイズとした比率で指定します。float 型で指定した場合は、幅と高さが同じ比率で伸縮されますが、Vector2 型で指定した場合は、X 要素が幅、Y 要素が高さの比率を表します。

effects パラメータには、反転オプションを表す Microsoft.Xna.Framework.Graphics.SpriteEffects 列挙型のメンバを指定します。

Microsoft.Xna.Framework.Graphics.SpriteEffects 列挙型
[FlagsAttribute]
public enum SpriteEffects

この列挙型には、水平方向に反転させることを表す FlipHorizontally メンバ、垂直方向に反転させることを表す FlipVertically メンバ、そして、反転させないことを表す None メンバが定義されています。FlipHorizontally メンバと FlipVertically メンバを組み合わせることも可能です。反転は、他の描画処理よりも前に行われるため、回転や伸縮は、反転されたテクスチャに対して行われます。

最後の layerDepth パラメータは、重ねられたスプライトの並べ替え優先順位を表す値です。このパラメータは、複数のスプライトの重ね合わせに用いられるものです。詳細は後述するので、この場では 0 を指定しましょう。

スプライトの原点

origin パラメータに指定するスプライトの原点は、スプライトの描画が開始される点を表します。スプライトの原点は、スプライトの描画を開始する座標や、スプライトの回転軸に影響を与えます。スプライトの回転は、原点を軸に行われます。デフォルトの場合、スプライトの左上隅が原点となっているため、左上隅を軸に回転します。

図1 原点と回転の関係
図1 原点と回転の関係

スプライトの中心を軸に回転させたい場合、原点をスプライトの中央に設定します。

スプライトの伸縮比率

scale パラメータに指定するスプライトの伸縮比率は、Rectangle 型の destinationRectangle パラメータによる描画領域の指定による伸縮とは異なります。destinationRectangle は、固定された領域にスプライトを伸縮するものですが、scale パラメータは 1 を基準とした元のサイズから相対的なサイズに伸縮します。値が 1 であれた元のサイズ、2 であれば 2 倍、0.5 であれば半分であること表します。

図2 伸縮比率
図2 伸縮比率

Draw() メソッドで描画するスプライトのサイズは、destinationRectangle パラメータを使った固定サイズか、scale パラメータを使った比率により相対的な伸縮の 2 つの方法によって操作できます。特定の領域内にはめ込むことを目的とするならば destinationRectangle パラメータ、演出などにより汎用的な伸縮処理には scale パラメータを使うとよいでしょう。

スプライトの反転

effects パラメータに指定する SpriteEffects 列挙型のメンバは、水平方向、垂直方向、またはその両方にスプライトを反転させることを表しています。SpriteEffects 列挙型の FlipHorizontally メンバと FlipVertically メンバをビット単位の論理和演算子 | で組み合わせることができます。

図3 反転
図3 反転

反転は、他の描画処理よりも前に行われます。スプライトの回転や伸縮は、反転した画像に対して行われます。  

ラジアンへの変換

rotation パラメータにラジアン単位で指定します。度ではないので注意してください。2π ラジアン(約 6.28)が 360 度に対応するため、1 ラジアンを度数に変換すると、360 / 2π (約 57.3)に一致します。度数で回転角度を指定するには、度をラジアンに変換しなければなりません。角度とラジアンの変換には Microsoft.Xna.Framework.MathHelper クラスを使うと簡単です。

Microsoft.Xna.Framework.MathHelper クラス
public static class MathHelper

このクラスは、いくつかの計算処理を行うメソッドと、円周率 PI などの主要な定数を提供しています。

度をラジアン単位に変換するには ToRadians() メソッドを使います。

MathHelper クラス ToRadians() メソッド
public static float ToRadians (float degrees)

このメソッドは、degrees パラメータに指定した角度をラジアンに変換した結果を返します。

逆に、ラジアンを度に変換する ToDegrees() メソッドも用意されています。 

MathHelper クラス ToDegrees() メソッド
public static float ToDegrees (float radians)

このメソッドは、radians パラメータに指定したラジアン単位の値を度に変換した結果を返します。

MathHelper クラスの ToRadians() メソッドを使うことで、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 Vector2 position;
    private Vector2 origin;
    private float rotation;

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

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

        position = new Vector2(texture.Width / 2 * 1.1F, texture.Height / 2 * 1.1F);
        origin = new Vector2(texture.Width / 2, texture.Height / 2);
        rotation = MathHelper.ToRadians(45);

        base.LoadContent();
    }

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

        sprite.Begin();
        sprite.Draw(texture, position, null, Color.White, rotation, origin, Vector2.One, SpriteEffects.None, 0);
        sprite.End();

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

コード1は、スプライトを 45 度回転させ描画します。これまでの Draw() メソッドよりもパラメータが多く複雑に見えますが、重要なのは rotation パラメータと origin パラメータです。このプログラムでは、LoadContent() メソッドでテクスチャを読み込んだ後、描画する座標を position フィールドに、スプライトの原点の座標を origin フィールドに、回転角度を rotation フィールドにそれぞれ代入し、Draw() メソッドのパラメータとして渡しています。

回転角度は 45 度を MathHelper クラスの ToRadians() メソッドでラジアンに変換したものです。実行結果をみると、画像が回転していることが分かります。回転は、origin フィールドに代入したスプライト上の座標を軸に行われます。このプログラムでは、スプライトの中心を原点としています。