회전 축을 지정하여 스프라이트를 회전합니다

페이지 업데이트 :
페이지 생성 날짜 :

요약

스프라이트의 회전 축의 위치는 지정되고 회전됩니다. 샘플에서는 시각적으로 볼 수 있도록 자동으로 회전됩니다.

回転軸を指定してスプライトを回転させる

운영 환경

필수 구성 요소

지원되는 XNA 버전
  • 2.0
  • 3.0
  • 3.1
  • 4.0
지원되는 플랫폼
  • Windows(XP SP2 이상, Vista, 7)
  • 엑스박스 360
  • 윈도우 폰 7
Windows 필수 버텍스 셰이더 버전 2.0
Windows 필수 픽셀 셰이더 버전 2.0

운영 환경

플랫폼
  • 윈도우 7
  • 엑스박스 360
  • Windows Phone 7 에뮬레이터

물질

이 경우 스프라이트의 중심에서 회전축을 지정하기 위해 텍스처를 로드할 때 이미지의 중심 위치를 가져옵니다. 값을 유지하기 위해 필드의 좌표 위치를 저장하는 Vector2를 선언합니다.

/// <summary>
/// テクスチャーの中心座標
/// </summary>
private Vector2 textureCenter = Vector2.Zero;

텍스처의 크기는 "Texture2D.Width" 및 "Texture2D.Height" 속성을 사용하여 얻을 수 있으므로 텍스처를 로드한 후 중심 위치를 찾기 위해 값을 반으로 줄입니다.

// テクスチャーをコンテンツパイプラインから読み込む
this.texture = this.Content.Load<Texture2D>("Texture");

// テクスチャーの中心座標を取得
this.textureCenter = new Vector2(this.texture.Width / 2, this.texture.Height / 2);

스프라이트를 회전할 때 회전 축은 기본적으로 스프라이트의 왼쪽 상단으로 설정됩니다.

デフォルトの回転軸位置

회전축을 변경하려면 "SpriteBatch.Draw" 메서드의 여섯 번째 인수에 회전 위치를 지정하여 스프라이트의 어느 위치로든 회전시킬 수 있습니다.

그러나 실행하면 알 수 있듯이 회전 축의 위치는 단순히 지정되는 것이 아니라 실제로 회전 축의 위치는 동일하며 스프라이트의 그리기 위치는 -origin에 의해 이동합니다. 이렇게 하면 스프라이트가 회전의 어느 지점에 있는 것처럼 보입니다.

回転軸位置を指定するとスプライトが相対的に移動される

회전축 위치를 이미지 중앙(샘플에서 64px)으로 지정하면 스프라이트가 이미지 크기의 절반(64px)만큼 왼쪽 상단으로 이동한 것을 확인할 수 있습니다.

회전 축의 위치가 동일하게 유지되기 때문에 스프라이트는 왼쪽 상단 위치를 기준으로 회전하고 회전 축은 (64, 64) 위치에 있습니다.

///// 回転軸指定 /////

// 回転なし
this.spriteBatch.Draw(this.texture,
   spritePos2, null, Color.White,
   0.0f, Vector2.Zero,
   1.0f, SpriteEffects.None, 0.0f);

// 回転あり
this.spriteBatch.Draw(this.texture,
   spritePos2, null, Color.White,
   MathHelper.ToRadians(this.realRotate), this.textureCenter,
   1.0f, SpriteEffects.None, 0.0f);

회전축만 직관적으로 지정하려면 원점 스프라이트를 이동하여 이 문제를 해결할 수 있습니다.

回転軸位置で左上に移動したスプライト スプライトを移動させてスプライトの中心で回転させているように見せる
스프라이트를 왼쪽 상단으로 이동합니다. 오른쪽 하단으로 이동하면 회전축만 지정된 것처럼 표시됩니다.
///// 回転軸指定、位置補正 /////

// 回転なし
this.spriteBatch.Draw(this.texture,
   spritePos3, null, Color.White,
   0.0f, Vector2.Zero,
   1.0f, SpriteEffects.None, 0.0f);

// 回転あり
this.spriteBatch.Draw(this.texture,
   spritePos3 + this.textureCenter, null, Color.White,
   MathHelper.ToRadians(this.realRotate), this.textureCenter,
   1.0f, SpriteEffects.None, 0.0f);

SpriteBatch.Draw 메서드

스프라이트 드로잉 배치 목록에 스프라이트를 추가합니다.

텍스처 텍스처2D 스프라이트로 표시할 텍스처를 지정합니다.
위치 벡터2 스프라이트가 표시되어야 하는 위치입니다. 화면의 왼쪽 상단을 기준으로 화면 좌표를 지정합니다. 스프라이트의 원점은 왼쪽 상단에 있습니다.
sourceRectangle (영문) Nullable<Rectangle입니다> 텍스처의 전송 영역을 지정합니다. 전체 텍스처를 스프라이트로 표시하려면 null을 지정할 수 있습니다. 이 매개 변수를 지정하면 임의의 영역만 스프라이트로 표시되도록 할 수 있습니다.
스프라이트의 색에 곱할 색을 지정합니다. Color.White를 지정하면 스프라이트의 기본 색상으로 표시됩니다. Color.Black을 지정하면 스프라이트는 색상에 관계없이 전체 검정색으로 표시됩니다. 공식은 "결과 = 스프라이트 색상 * 색상"입니다.
회전 뜨다 스프라이트의 회전 각도입니다. 단위는 라디안으로 지정됩니다. 회전축은 스프라이트의 왼쪽 상단에 있습니다.
기원 벡터2 스프라이트를 회전할 때 회전축의 위치를 지정합니다. 스프라이트의 어느 위치가 회전축인지 지정하지만 실제로는 회전축의 위치는 스프라이트의 왼쪽 상단에 고정되고 스프라이트의 표시 위치는 -origin에 의해 이동합니다.
저울 뜨다 스프라이트의 배율을 지정합니다. 1.0을 기준으로 세로 및 가로로 크기를 조정합니다. 확대의 원점은 스프라이트의 왼쪽 상단 모서리에 있습니다.
효과 스프라이트 이펙트 스프라이트의 반전 효과를 지정합니다. 다른 작업을 수행하지 않으면 SpriteEffects.None을 지정합니다.
layerDepth (레이어깊이) 뜨다 스프라이트가 표시되는 깊이를 지정합니다. 주로 전경과 후면에 스프라이트를 표시하는 데 사용됩니다. 0.0~1.0 범위로 지정하며, 0.0은 앞면, 1.0은 뒷면입니다.

모든 코드

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif

namespace SetOriginRotateSprite
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// グラフィックデバイス管理クラス
        /// </summary>
        private GraphicsDeviceManager graphics = null;

        /// <summary>
        /// スプライトのバッチ化クラス
        /// </summary>
        private SpriteBatch spriteBatch = null;

        /// <summary>
        /// テクスチャー
        /// </summary>
        private Texture2D texture = null;

        /// <summary>
        /// テクスチャーの中心座標
        /// </summary>
        private Vector2 textureCenter = Vector2.Zero;

        /// <summary>
        /// リアルタイムに増加する回転量
        /// </summary>
        private float realRotate = 0.0f;


        /// <summary>
        /// GameMain コンストラクタ
        /// </summary>
        public GameMain()
        {
            // グラフィックデバイス管理クラスの作成
            this.graphics = new GraphicsDeviceManager(this);

            // ゲームコンテンツのルートディレクトリを設定
            this.Content.RootDirectory = "Content";

#if WINDOWS_PHONE
            // Windows Phone のデフォルトのフレームレートは 30 FPS
            this.TargetElapsedTime = TimeSpan.FromTicks(333333);

            // バックバッファサイズの設定
            this.graphics.PreferredBackBufferWidth = 480;
            this.graphics.PreferredBackBufferHeight = 800;

            // フルスクリーン表示
            this.graphics.IsFullScreen = true;
#endif
        }

        /// <summary>
        /// ゲームが始まる前の初期化処理を行うメソッド
        /// グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを書いてください

            // コンポーネントの初期化などを行います
            base.Initialize();
        }

        /// <summary>
        /// ゲームが始まるときに一回だけ呼ばれ
        /// すべてのゲームコンテンツを読み込みます
        /// </summary>
        protected override void LoadContent()
        {
            // テクスチャーを描画するためのスプライトバッチクラスを作成します
            this.spriteBatch = new SpriteBatch(this.GraphicsDevice);

            // テクスチャーをコンテンツパイプラインから読み込む
            this.texture = this.Content.Load<Texture2D>("Texture");

            // テクスチャーの中心座標を取得
            this.textureCenter = new Vector2(this.texture.Width / 2, this.texture.Height / 2);
        }

        /// <summary>
        /// ゲームが終了するときに一回だけ呼ばれ
        /// すべてのゲームコンテンツをアンロードします
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ContentManager で管理されていないコンテンツを
            //       ここでアンロードしてください
        }

        /// <summary>
        /// 描画以外のデータ更新等の処理を行うメソッド
        /// 主に入力処理、衝突判定などの物理計算、オーディオの再生など
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Update(GameTime gameTime)
        {
            // Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
            // ゲームを終了させます
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            // 回転量を増やす
            this.realRotate += (float)gameTime.ElapsedGameTime.TotalSeconds * 60.0f;

            // 登録された GameComponent を更新する
            base.Update(gameTime);
        }

        /// <summary>
        /// 描画処理を行うメソッド
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Draw(GameTime gameTime)
        {
            // 画面を指定した色でクリアします
            this.GraphicsDevice.Clear(Color.CornflowerBlue);

            // スプライトの描画準備
            this.spriteBatch.Begin();

            Vector2 spritePos1;
            Vector2 spritePos2;
            Vector2 spritePos3;
#if WINDOWS || XBOX
            spritePos1 = new Vector2(150.0f, 200.0f);
            spritePos2 = new Vector2(350.0f, 200.0f);
            spritePos3 = new Vector2(550.0f, 200.0f);
#else
            spritePos1 = new Vector2(200.0f, 150.0f);
            spritePos2 = new Vector2(200.0f, 350.0f);
            spritePos3 = new Vector2(200.0f, 550.0f);
#endif

            ///// 回転軸デフォルト /////

            // 回転なし
            this.spriteBatch.Draw(this.texture,
               spritePos1, null, Color.White,
               0.0f, Vector2.Zero,
               1.0f, SpriteEffects.None, 0.0f);

            // 回転あり
            this.spriteBatch.Draw(this.texture,
               spritePos1, null, Color.White,
               MathHelper.ToRadians(this.realRotate), Vector2.Zero,
               1.0f, SpriteEffects.None, 0.0f);

            ///// 回転軸指定 /////

            // 回転なし
            this.spriteBatch.Draw(this.texture,
               spritePos2, null, Color.White,
               0.0f, Vector2.Zero,
               1.0f, SpriteEffects.None, 0.0f);

            // 回転あり
            this.spriteBatch.Draw(this.texture,
               spritePos2, null, Color.White,
               MathHelper.ToRadians(this.realRotate), this.textureCenter,
               1.0f, SpriteEffects.None, 0.0f);

            ///// 回転軸指定、位置補正 /////

            // 回転なし
            this.spriteBatch.Draw(this.texture,
               spritePos3, null, Color.White,
               0.0f, Vector2.Zero,
               1.0f, SpriteEffects.None, 0.0f);

            // 回転あり
            this.spriteBatch.Draw(this.texture,
               spritePos3 + this.textureCenter, null, Color.White,
               MathHelper.ToRadians(this.realRotate), this.textureCenter,
               1.0f, SpriteEffects.None, 0.0f);

            // スプライトの一括描画
            this.spriteBatch.End();

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}