程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> XNA基礎(02) 繪制基礎

XNA基礎(02) 繪制基礎

編輯:關於.NET

在所有的圖形引擎中,繪制都是最基礎的部分,本文將介紹在XNA框架中與繪制相關的基礎知識。

在XNA中,我們使用SpriteBatch來進行繪制。首先,我們需要使用SpriteBatch來繪制什麼了?是精靈 Sprite,對。

那麼Sprite通過什麼來表現了?是紋理,比如2D紋理Texture2D。嗯,你可以把紋理想象成Sprite的外 表,比如我們制作的一幅精靈圖片,就是一個紋理。

我們要如何才能把一幅圖片加載到我們的游戲中來作為一個Sprite的紋理了?這要通過素材管道 Content Pipeline。所謂素材,包括我們游戲中要用到的圖片、模型、聲音等,比如一個紋理圖片就是素 材的一種。素材管道就很容易理解了,它可以把我們需要的素材導入到我們的游戲中,以XNA能夠識別的 正確的格式。而且,格式的識別與轉換是在編譯期完成的。

在新建的XNA項目中,會有一個默認的Content文件夾,通常,我們會把所有的素材放在這個地方,並 且根據素材的種類我們會在其下創建一些子文件夾,比如Image子文件夾用來存放所有的圖片素材,Audio 文件夾用來存放聲音素材等。

當一個物件別被識別為素材後,就會有一個唯一的資產名稱AssetName來標記它,我們可以通過素材的 屬性頁來查看素材的AssetName屬性並修改它。

下面我們可以用素材管理器ContentManager將一個素材導入到游戲中:

Texture2D texture;

texture = Content.Load<Texture2D>(@"Image\logo"); //在上文提到的LoadContent方法中調 用

很多時候,我們的圖片需要是透明的,那麼如何在SpriteBatch繪制的時候將圖片繪制為透明了?有兩 種方法:要麼圖片具有透明的背景,要麼在制作圖片時將需要透明的部分設置為純正的洋紅色(255,0, 255)。除此之外,還需要注意,SpriteBlendMode模式必須為AlphaBlend(這也是默認模式,稍後會提到 ),才能達到我們期望的透明效果。

在進行渲染時,我們還需要注意層深度(Layer Depth)。所謂Layer Depth,指的是你需要將目標 Sprite繪制在哪一個深度的層次。默認情況下,SpriteBatch會根據你調用的順序來決定Layer Depth的相 對值,比如,你先調用SpriteBatch繪制Sprite A,然後調用SpriteBatch在同一位置繪制Sprite B,那麼 ,Sprite B就會把Sprite A擋住。如果我們依靠調用SpriteBatch繪制的順序來決定Sprite的深度,那就 太不靈活了,為此,調用SpriteBatch繪制方法時,你可以指定一個代表層次深度的參數(范圍0~1)來指 示SpriteBatch按照我們希望的順序來繪制對象。

有了上面的這些基礎之後,我們可以詳細講解一下XNA中的渲染過程。每次渲染的過程都類似下面的模 式:

protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.Black);
  spriteBatch.Begin();
  spriteBatch.Draw(……);
  spriteBatch.End();
  base.Draw(gameTime);
}

(1)GraphicsDevice.Clear()方法用於清除屏幕背景。

(2)SpriteBatch.Begin()方法用於通知顯卡准備繪制場景。

(3)輪流調用SpriteBatch.Draw()繪制所有組件。

(4)SpriteBatch.End()方法用於告訴顯卡繪制已經完成。

(5)最後,顯卡顯示繪制的結果。

SpriteBatch.Begin()方法有一個接受參數的重載:

void Begin(SpriteBlendMode blendMode, SpriteSortMode sortMode, SaveStateMode  stateMode, Matrix transformMatrix) ;

SpriteBlendMode 參數決定了Sprite的顏色與背景顏色的混合模式,默認為AlphaBlend,我們剛才提 到過。

SpriteSortMode參數決定了Sprite的排序模型,即與前面的Layer Depth關聯。

SaveStateMode參數用於控制是否保存圖形設備的狀態。

TransformMatrix參數用於控制旋轉、縮放等。

接下來我們看最重要的繪制Draw方法:

void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle,  Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects,  float layerDepth);

第一個Texture2D參數,表示要繪制Sprite的紋理。

第二個Vector2參數,表示要繪制的Sprite的左上角的位置在哪裡 。

第三個Rectangle參數,表示要繪制源紋理的哪一個區域,如果要繪制紋理的全部部分,則傳null。

第四個Color參數,表示繪制時所調制的顏色通道。

第五個參數rotation,表示要旋轉的角度。

第六個參數origin,表示圍繞哪個位置進行旋轉。

第七個參數scale,表示繪制時要縮放的比例。

第八個參數effects,表示是否進行翻轉。SpriteEffects.FlipHorizontally -- 水平翻轉; SpriteEffects.FlipVertically -- 垂直翻轉。

最後一個參數layerDepth,就是我們前面說過的要在哪一個深度層次繪制對象。

最後,要解釋一下,為什麼需要在每次Draw調用時,都先調用GraphicsDevice.Clear()方法清除屏幕 然後再重新繪制所有物件了?這樣性能不是很差嗎?而且有時候我們可能只有極小的一部分需要重新繪制 。

假設我們每次只重新繪制變動的那一部分,那我們就需要一個復雜的管理器來追蹤每一個部分的變動 ,這樣我們才有可能知道要重繪哪一部分。你可以想象一下,這個追蹤的過程是相當復雜的。而且還存在 這樣的情況,那就是當一個Sprite移動時,它後面原先被擋住的Sprite會露出來,而這個Sprite可能又會 擋住另外一個Sptrite的一部分,這樣一來就更加復雜了。所以,每次重繪整個屏幕並不是一個壞的idea 。     

今天就講到這裡,下一節我們將講述與FrameRate相關的知識。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved