Utilizarea parametrilor stratului pentru a crea un context sprite

Pagina actualizată :
Data creării paginii :

rezumat

Utilizați valoarea de adâncime a stratului pentru a specifica contextul sprite-ului.

レイヤーパラメータを使用してスプライトの前後関係を作る

Mediul de operare

Cerințe preliminare

Versiuni XNA acceptate
  • 2.0
  • 3.0
  • 3.1
  • 4.0
Platforme acceptate
  • Windows (XP SP2 sau o versiune ulterioară, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Versiunea Vertex Shader necesară pentru Windows 2.0
Versiunea Pixel Shader necesară pentru Windows 2.0

Mediul de operare

peron
  • Windows 7
  • Xbox 360
  • Windows Phone 7 Emulator

substanță

În mod normal, atunci când desenați un sprite, acesta este desenat astfel încât ceea ce desenați mai târziu să fie în fața dvs., dar prin sortarea după valoarea adâncimii, puteți clarifica contextul indiferent de ordinea în care este apelată metoda SpriteBatch.Draw.

Pentru a sorta după valoarea adâncimii sprite-ului, specificați "SpriteSortMode.BackToFront" ca prim argument la metoda "SpriteBatch.Begin". Este o metodă de procesare care se bazează pe sprite în spate și suprascrie sprite în prim-plan.

// 一つでも半透明、透明要素があるスプライトの場合はこちらの引数を使用
this.spriteBatch.Begin(SpriteSortMode.BackToFront, null);

Cu toate acestea, dacă doriți să desenați doar un sprite care este semi-transparent sau nu are deloc elemente transparente, îl puteți desena mai repede specificând următoarele.

// 深度バッファを使用して前後関係を有効にし描画するように指定
// 完全な不透明スプライトのみ描画する場合はこちらが高速
this.spriteBatch.Begin(SpriteSortMode.FrontToBack,
                       BlendState.Opaque,
                       null,
                       DepthStencilState.Default,
                       null);

Al patrulea argument este "DepthStencilState.Default", care scrie și informații de "adâncime" pe fiecare pixel atunci când sprite-ul este desenat. Când informațiile de adâncime sunt scrise, este posibil să se determine că obiectul care urmează să fie desenat (în pixeli) după acea poziție nu trebuie scris, astfel încât costul desenului este mult redus.

Din motivele de mai sus, dacă desenați mai întâi sprite-ul în prim-plan, costul de desen al sprite-ului care se suprapune în spatele acestuia va scădea, deci este sortat astfel încât să fie desenat din față, specificând "SpriteSortMode.FrontToBack" ca primul argument pentru a desena din prim-plan.

Cu toate acestea, acest lucru este util doar atunci când desenați un sprite opac cu un element de culoare complet neglijabil în spatele său. În cazul sprite-urilor semitransparente sau opace, valoarea adâncimii este scrisă pe fiecare pixel chiar dacă este un pixel semitransparent sau transparent, deci dacă desenați din față, sprite-ul din spatele dvs. Acesta este motivul pentru care "SpriteSortMode.BackToFront" este specificat în desenul caracterului. (Deoarece alți pixeli decât forma textului sunt transparenți)

Apropo, ca urmare a unui test de desenare a 30.000 de sprite-uri în mediul meu, a fost de aproximativ 3 ori mai rapid să desenez din față folosind valoarea adâncimii decât din spate. Desigur, depinde de numărul de foi care trebuie desenate, de gradul de suprapunere, de dimensiune etc., precum și de mediul de execuție, așa că vă rugăm să încercați singur.

SpriteBatch.Begin metodă

Numiți-l înainte de a desena sprite-ul. Intern, facem setările necesare pentru desenarea sprite-urilor.

sortareMod SpriteSortMode Specifică ordinea în care sprite-urile sunt extrase din enumerarea SpriteSortMode. Dacă doriți să desenați din spate, specificați SpriteSortMode.BackToFront. Dacă doriți să desenați din față, specificați SpriteSortMode.FrontToBack.
blendState BlendState Cum se amestecă culoarea sprite-ului care urmează să fie desenat cu culoarea de fundal. În mod implicit, este specificat BlendState.AlphaBlend, dar în acest caz, sprite-ul care urmează să fie desenat este complet opac, astfel încât BlendState.Opaque este specificat fără a lua în considerare culoarea de fundal.
samplerState SamplerState Cum este eșantionată textura. Dacă se specifică null, se specifică valoarea implicită SamplerState.LinearClamp.
adâncimeStencilState DepthStencilState Specifică modul în care se utilizează tamponul de tip adâncime. Dacă se specifică null, se utilizează DepthStencilState.None, care nu utilizează un tampon de tip de adâncime. Dacă doriți să utilizați un tampon de tip de adâncime, specificați DepthStencilState.Default.
rasterizerStat Statul Rasterizer Specifică o metodă de rasterizare, cum ar fi eliminarea înapoi. Dacă se specifică null, se specifică valoarea implicită RasterizerState.CullCounterClockwise.

Pentru a desena un sprite, specificați o valoare de adâncime ca al nouălea argument pentru metoda SpriteBatch.Draw. Valorile care pot fi setate aici sunt în intervalul 0.0~1.0, 0.0 fiind cel mai important și 1.0 fiind cel mai din spate.

// 最背面に描画(赤)
this.spriteBatch.Draw(this.texture, new Vector2(150.0f, 50.0f), null,
    Color.Red, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

// 最前面に描画(緑)
this.spriteBatch.Draw(this.texture, new Vector2(110.0f, 90.0f), null,
    Color.Green, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);

// 2つのスプライトの間に描画(青)
this.spriteBatch.Draw(this.texture, new Vector2(190.0f, 130.0f), null,
    Color.Blue, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);

SpriteBatch.Draw metodă

Adaugă un sprite la lista de loturi de desen sprite.

textură Textură2D Specifică textura de afișat ca sprite.
poziție Vector2 Poziția în care ar trebui să fie afișat sprite-ul. Specificați coordonatele ecranului în raport cu partea din stânga sus a ecranului. Originea sprite-ului va fi în poziția din stânga sus.
sursăDreptunghi Anulabil<Dreptunghi> Specifică zona de transfer pentru textură. Dacă doriți ca întreaga textură să fie afișată ca sprite, puteți specifica null. Dacă specificați acest parametru, puteți face ca doar o zonă arbitrară să apară ca sprite.
culoare Culoare Specifică culoarea pentru a înmulți culoarea sprite-ului. Dacă specificați Color.White, acesta este afișat în culoarea primară a sprite-ului. Dacă este specificat Color.Black, sprite-ul este afișat în negru complet, indiferent de culoarea sa. Formula este "Rezultat = culoare sprite * culoare".
rotație pluti Unghiul de rotație al spritelui. Unitățile sunt specificate în radian. Axa de rotație va fi în stânga sus a sprite-ului.
origine Vector2 Specifică poziția axei de rotație la rotirea sprite-ului. Specificați care poziție a sprite-ului este axa de rotație, dar în realitate, poziția axei de rotație este fixată în stânga sus a sprite-ului, iar poziția de afișare a sprite-ului este mutată de -origin.
cântar pluti Specifică mărirea sprite-ului. Se scalează vertical și orizontal în raport cu 1.0. Originea măririi va fi în colțul din stânga sus al sprite-ului.
Efecte Efecte sprite Specifică efectul de răsturnare al sprite-ului. Dacă nu faceți nimic altceva, specificați SpriteEffects.None.
stratAdâncime pluti Specifică adâncimea la care este afișat sprite-ul. Este folosit în principal pentru a afișa sprite-uri în prim-plan și în spate. Specificați în intervalul de 0.0~1.0, unde 0.0 este partea din față și 1.0 este partea din spate.

În programul de mai sus, metoda SpriteBatch.Draw este apelată în ordinea "roșu", "verde" și "albastru", dar fiecare valoare de adâncime este setată la "roșu (1.0)", "verde (0.0)" și "albastru (0.5)", astfel încât să puteți vedea că roșu este desenat în spate și verde este desenat în prim-plan.

深度値を使用したスプライトの描画

Toate codurile

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 LayerDepthSprite
{
    /// <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>
        /// 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");
        }

        /// <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();
            }

            // TODO: ここに更新処理を記述してください

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

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

            // 深度バッファを使用して前後関係を有効にし描画するように指定
            // 完全な不透明スプライトのみ描画する場合はこちらが高速
            this.spriteBatch.Begin(SpriteSortMode.FrontToBack,
                                   BlendState.Opaque,
                                   null,
                                   DepthStencilState.Default,
                                   null);

            // 一つでも半透明、透明要素があるスプライトの場合はこちらの引数を使用
            //this.spriteBatch.Begin(SpriteSortMode.BackToFront, null);

            // 最背面に描画(赤)
            this.spriteBatch.Draw(this.texture, new Vector2(150.0f, 50.0f), null,
                Color.Red, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

            // 最前面に描画(緑)
            this.spriteBatch.Draw(this.texture, new Vector2(110.0f, 90.0f), null,
                Color.Green, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);

            // 2つのスプライトの間に描画(青)
            this.spriteBatch.Draw(this.texture, new Vector2(190.0f, 130.0f), null,
                Color.Blue, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.5f);

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

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