Ús de paràmetres de capa per crear context de sprites
resum
Utilitzeu el valor de profunditat de la capa per especificar el context de l'sprite.
Entorn operatiu
Prerequisits
Versions XNA compatibles |
|
Plataformes compatibles |
|
Versió del shader de vèrtex necessària per al Windows | 2.0 |
Versió de Pixel Shader necessària per a Windows | 2.0 |
Entorn operatiu
plataforma |
|
substància
Normalment, quan dibuixeu un sprite, es dibuixa de manera que el que dibuixeu més tard estigui davant vostre, però ordenant per valor de profunditat, podeu aclarir el context independentment de l'ordre en què es cridi el mètode SpriteBatch.Draw.
Per ordenar pel valor de profunditat de sprite, especifiqueu "SpriteSortMode.BackToFront" com a primer argument del mètode "SpriteBatch.Begin". És un mètode de processament que extreu de l'sprite a la part posterior i sobreescriu l'sprite en primer pla.
// 一つでも半透明、透明要素があるスプライトの場合はこちらの引数を使用
this.spriteBatch.Begin(SpriteSortMode.BackToFront, null);
Tanmateix, si voleu dibuixar només un sprite que sigui semitransparent o que no tingui elements transparents, podeu dibuixar-lo més ràpidament especificant el següent.
// 深度バッファを使用して前後関係を有効にし描画するように指定
// 完全な不透明スプライトのみ描画する場合はこちらが高速
this.spriteBatch.Begin(SpriteSortMode.FrontToBack,
BlendState.Opaque,
null,
DepthStencilState.Default,
null);
El quart argument és "DepthStencilState.Default", que també escriu informació de "profunditat" a cada píxel quan es dibuixa l'sprite. Quan s'escriu la informació de profunditat, és possible determinar que l'objecte a dibuixar (en píxels) després d'aquesta posició no necessita ser escrit, de manera que el cost de dibuix es redueix considerablement.
Per les raons anteriors, si dibuixeu primer l'sprite en primer pla, el cost de dibuix de l'sprite que se superposa darrere d'ell disminuirà, de manera que s'ordenarà de manera que es dibuixi des del davant especificant "SpriteSortMode.FrontToBack" com el primer argument per dibuixar des del primer pla.
Tanmateix, això només és útil quan es dibuixa un sprite opac amb un element de color completament insignificant al darrere. En el cas dels sprites semitransparents o opacs, el valor de profunditat s'escriu a cada píxel encara que sigui un píxel semitransparent o transparent, de manera que si dibuixeu des del frontal, no es mostrarà l'sprite que hi ha darrere. És per això que "SpriteSortMode.BackToFront" s'especifica en el dibuix del personatge. (Perquè els píxels diferents de la forma del text són transparents)
Per cert, com a resultat d'una prova de dibuixar 30.000 sprites al meu entorn, va ser aproximadament 3 vegades més ràpid dibuixar des de la part frontal utilitzant el valor de profunditat que des de la part posterior. Per descomptat, depèn del nombre de fulls a dibuixar, del grau de superposició, de la mida, etc., així com de l'entorn d'execució, així que proveu-ho vosaltres mateixos.
SpriteBatch.Begin
mètode
Digueu-lo abans de dibuixar l'sprite. Internament, estem fent els paràmetres necessaris per dibuixar sprites.
mode d'ordenació | SpriteSortMode | Especifica l'ordre en què els sprites s'extreuen de l'enumeració SpriteSortMode. Si voleu dibuixar des de la part posterior, especifiqueu SpriteSortMode.BackToFront. Si voleu dibuixar des del davant, especifiqueu SpriteSortMode.FrontToBack. |
Estat de barreja | Estat de barreja | Com barrejar el color de l'sprite a dibuixar amb el color de fons. Per defecte, s'especifica BlendState.AlphaBlend, però en aquest cas, l'sprite que s'ha de dibuixar és completament opac, de manera que s'especifica BlendState.Opaque sense tenir en compte el color de fons. |
samplerState | SamplerState | Com es mostra la textura. Si s'especifica null, s'especifica el valor per defecte SamplerState.LinearClamp. |
profunditatEstat de l'escàncil | DepthStencilState | Especifica com s'utilitza la memòria intermèdia de plantilles de profunditat. Si s'especifica null, s'utilitza DepthStencilState.None, que no utilitza una memòria intermèdia de plantilla de profunditat. Si voleu utilitzar una memòria intermèdia de plantilles de profunditat, especifiqueu DepthStencilState.Default. |
rasterizerEstat | Estat de Rasterizer | Especifica un mètode de rasterització, com ara la selecció inversa. Si s'especifica null, s'especifica el valor per defecte RasterizerState.CullCounterClockwise. |
Per dibuixar un sprite, especifiqueu un valor de profunditat com a novè argument del mètode SpriteBatch.Draw. Els valors que es poden establir aquí es troben en el rang de 0,0 ~ 1,0, sent 0,0 el més important i 1,0 el més posterior.
// 最背面に描画(赤)
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
mètode
Afegeix un sprite a la llista de lots de dibuix de sprites.
textura | Textura2D | Especifica la textura que es mostrarà com a sprite. |
posició | Vector2 | La posició on s'ha de mostrar l'sprite. Especifiqueu les coordenades de la pantalla en relació amb la part superior esquerra de la pantalla. L'origen de l'sprite estarà a la posició superior esquerra. |
fontRectangle | Nullable<Rectangle> | Especifica l'àrea de transferència de la textura. Si voleu que tota la textura es mostri com a sprite, podeu especificar null. Si especifiqueu aquest paràmetre, només podeu fer que una àrea arbitrària aparegui com a sprite. |
color | Color | Especifica el color per multiplicar el color de l'sprite. Si especifiqueu Color.White, es mostra en el color primari de l'sprite. Si s'especifica Color.Black, l'sprite es mostra en negre complet, independentment del seu color. La fórmula és "Resultat = color de l'sprite * color". |
rotació | flotar | L'angle de rotació de l'sprite. Les unitats s'especifiquen en radian. L'eix de rotació estarà a la part superior esquerra de l'sprite. |
origen | Vector2 | Especifica la posició de l'eix de rotació en girar l'sprite. Especifiqueu quina posició de l'sprite és l'eix de rotació, però en realitat, la posició de l'eix de rotació es fixa a la part superior esquerra de l'sprite i la posició de visualització de l'sprite es mou per -origin. |
escala | flotar | Especifica l'ampliació de l'sprite. Escala verticalment i horitzontalment en relació amb 1.0. L'origen de l'augment estarà a la cantonada superior esquerra de l'sprite. |
Efectes | Efectes de sprite | Especifica l'efecte de volteig de l'sprite. Si no feu res més, especifiqueu SpriteEffects.None. |
capaProfunditat | flotar | Especifica la profunditat a la qual es mostra l'sprite. S'utilitza principalment per mostrar sprites en primer pla i al darrere. Especifiqueu en l'interval de 0,0 ~ 1,0, on 0,0 és la part davantera i 1,0 és la part posterior. |
En el programa anterior, el mètode SpriteBatch.Draw s'anomena en l'ordre de "vermell", "verd" i "blau", però cada valor de profunditat s'estableix en "vermell (1.0)", "verd (0.0)" i "blau (0.5)", de manera que podeu veure que el vermell es dibuixa a la part posterior i el verd es dibuixa en primer pla.
Tots els codis
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);
}
}
}