Použitie parametrov vrstvy na vytvorenie kontextu sprite

Stránka aktualizovaná :
Dátum vytvorenia strany :

súhrn

Použite hodnotu hĺbky vrstvy na určenie kontextu sprita.

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

Prevádzkové prostredie

Predpoklady

Podporované verzie XNA
  • 2.0
  • 3.0
  • 3.1
  • 4.0
Podporované platformy
  • Windows (XP SP2 alebo novší, Vista, 7)
  • Konzola Xbox 360
  • Windows Phone 7
Windows vyžaduje verziu tieňovača vrcholov 2.0
Windows vyžaduje verziu Pixel Shader 2.0

Prevádzkové prostredie

nástupište
  • Windows 7
  • Konzola Xbox 360
  • Emulátor Windows Phone 7

látka

Za normálnych okolností, keď kreslíte sprite, je nakreslený tak, že to, čo nakreslíte neskôr, je pred vami, ale zoradením podľa hodnoty hĺbky môžete objasniť kontext bez ohľadu na poradie, v akom sa metóda SpriteBatch.Draw volá.

Ak chcete zoradiť podľa hodnoty hĺbky sprajtu, zadajte "SpriteSortMode.BackToFront" ako prvý argument metódy "SpriteBatch.Begin". Je to metóda spracovania, ktorá čerpá zo sprita vzadu a prepisuje sprita v popredí.

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

Ak však chcete nakresliť iba postavu, ktorá je polopriehľadná alebo nemá žiadne priehľadné prvky, môžete ju nakresliť rýchlejšie zadaním nasledujúcich možností.

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

Štvrtým argumentom je "DepthStencilState.Default", ktorý tiež zapisuje informácie o "hĺbke" do každého pixelu pri kreslení sprajta. Keď je zapísaná informácia o hĺbke, je možné určiť, že objekt, ktorý sa má nakresliť (v pixeloch) po tejto polohe, nie je potrebné zapisovať, takže náklady na kreslenie sa výrazne znížia.

Z vyššie uvedených dôvodov, ak nakreslíte sprita do popredia ako prvý, náklady na kreslenie sprita, ktorý sa za ním prekrýva, sa znížia, takže sa zoradí tak, aby sa nakreslil spredu zadaním "SpriteSortMode.FrontToBack" ako prvého argumentu, ktorý sa má kresliť z popredia.

To je však užitočné iba pri kreslení nepriehľadného sprita s úplne zanedbateľným farebným prvkom za ním. V prípade polopriehľadných alebo nepriehľadných spritov sa hodnota hĺbky zapíše do každého pixelu, aj keď ide o polopriehľadný alebo priehľadný pixel, takže ak kreslíte spredu, sprite za vami sa nezobrazí. To je dôvod, prečo je "SpriteSortMode.BackToFront" špecifikovaný vo výkrese znakov. (Pretože iné pixely ako tvar textu sú priehľadné)

Mimochodom, v dôsledku testu kreslenia 30 000 spritov v mojom prostredí bolo asi 3-krát rýchlejšie kresliť spredu pomocou hodnoty hĺbky ako zozadu. Samozrejme, závisí to od počtu listov, ktoré sa majú nakresliť, stupňa prekrytia, veľkosti atď., ako aj od prostredia vykonávania, preto si to vyskúšajte sami.

SpriteBatch.Begin metóda

Nazvite to pred nakreslením škriatka. Interne robíme potrebné nastavenia pre kreslenie škriatkov.

Režim triedenia SpriteSortMode Určuje poradie, v ktorom sa sprity vyberajú z enumerácie SpriteSortMode. Ak chcete kresliť zozadu, zadajte SpriteSortMode.BackToFront. Ak chcete kresliť spredu, zadajte SpriteSortMode.FrontToBack.
blendState Stav prelínania Ako zmiešať farbu škriatka, ktorý sa má nakresliť, s farbou pozadia. V predvolenom nastavení je špecifikovaný BlendState.AlphaBlend, ale v tomto prípade je pohyblivý sprajt, ktorý sa má nakresliť, úplne nepriehľadný, takže BlendState.Opaque je špecifikovaný bez zohľadnenia farby pozadia.
Stav vzorkovníka Stav vzorkovníka Ako sa odoberá vzorka textúry. Ak je zadaná hodnota null, zadá sa predvolená hodnota SamplerState.LinearClamp.
hĺbkaStencilState HĺbkaStencilState Určuje, ako sa použije vyrovnávacia pamäť vzorkovnice hĺbky. Ak je zadaná hodnota null, použije sa DepthStencilState.None, ktorá nepoužíva vyrovnávaciu pamäť vzorkovnice hĺbky. Ak chcete použiť vyrovnávaciu pamäť vzorkovnice hĺbky, zadajte DepthStencilState.Default.
rasterizerState Rasterizátorský štát Určuje metódu rasterizácie, ako je napríklad spätné vyraďovanie. Ak je zadaná hodnota null, zadá sa predvolená hodnota RasterizerState.CullCounterClockwise.

Ak chcete nakresliť sprajta, zadajte hodnotu hĺbky ako deviaty argument metódy SpriteBatch.Draw. Hodnoty, ktoré je tu možné nastaviť, sú v rozsahu 0,0~1,0, pričom 0,0 je najvyššie a 1,0 je najzadnejšie.

// 最背面に描画(赤)
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 metóda

Pridá sprita do zoznamu dávok kreslenia sprite.

textúra Textúra2D Určuje textúru, ktorá sa má zobraziť ako sprajt.
pozícia Vektor2 Poloha, kde by sa mal sprite zobraziť. Zadajte súradnice obrazovky vzhľadom na ľavú hornú časť obrazovky. Pôvod škriatku bude v ľavej hornej polohe.
zdrojObdĺžnik Hodnota null<obdĺžnik> Určuje oblasť prenosu textúry. Ak chcete, aby sa celá textúra zobrazovala ako sprajt, môžete zadať hodnotu null. Ak zadáte tento parameter, môžete ako sprajt zobraziť iba ľubovoľnú oblasť.
farba Farba Určuje farbu, ktorou sa má vynásobiť farba postavy. Ak zadáte Color.White, zobrazí sa v primárnej farbe pohyblivého symbolu. Ak je zadaná možnosť Color.Black, sprite sa zobrazí v úplnej čiernej farbe bez ohľadu na jeho farbu. Vzorec je "Výsledok = farba sprite * farba".
rotácia plávať Uhol natočenia škriatka. Jednotky sú uvedené v radiáne. Os otáčania bude v ľavom hornom rohu sprite.
pôvod Vektor2 Určuje polohu osi otáčania pri otáčaní postavy. Určíte, ktorá pozícia pohyblivého symbolu je os otáčania, ale v skutočnosti je poloha osi otáčania pevne stanovená v ľavom hornom rohu pohyblivého symbolu a zobrazená pozícia sprita sa presunie o -origin.
stupnica plávať Určuje zväčšenie pohyblivého symbolu. Mierka vertikálne a horizontálne vzhľadom na 1,0. Pôvod zväčšenia bude v ľavom hornom rohu škriatka.
Účinky SpriteEffects Určuje efekt preklopenia sprita. Ak neurobíte nič iné, zadajte SpriteEffects.None.
vrstvaHĺbka plávať Určuje hĺbku, v ktorej sa sprajt zobrazí. Používa sa hlavne na zobrazenie škriatov v popredí a vzadu. Zadajte v rozsahu 0.0~1.0, kde 0.0 je predná strana a 1.0 je zadná strana.

Vo vyššie uvedenom programe sa metóda SpriteBatch.Draw volá v poradí "červená", "zelená" a "modrá", ale každá hodnota hĺbky je nastavená na "červená (1.0)", "zelená (0.0)" a "modrá (0.5)", takže môžete vidieť, že červená je nakreslená vzadu a zelená je nakreslená v popredí.

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

Všetky kódy

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