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

XNA基礎(03) 動畫與幀率

編輯:關於.NET

我們要做的2D和3D游戲離不開動畫,那麼在XNA中如何實現動畫了?

首先,我們來看最簡單的動畫 —— 移動。

要移動一個Sprite非常簡單,我們只需要在Game1.Update()方法中改變Sprite的位置坐標,在下次 Game1.Draw()方法被調用時,屏幕上顯示的Sprite就被移動了。

接下來,我們看復雜一點的動畫,比如炸彈的爆炸效果,我們可以這樣來實現,制作一系列的圖片, 每張圖片都是爆炸過程中某一狀態的表現,如下所示:

上面的20個小圖片表現了一個爆炸從初始到結束的所有狀態,在實際制作時,我們通常將這些圖片按 順序制作在一張大圖中,並且保證大圖中每個小圖的尺寸是完全一樣的。我們稱這樣的大圖為精靈幀序列 圖Sprite Sheets。

有了爆炸的Sprite Sheets,我們可以通過在Game1.Update()方法中改變下一個要顯示的小圖片的索 引(比如[2,3]),再根據索引以及小圖片的尺寸計算出該將要顯示的小圖片在Sprite Sheets中的相對位 置,這樣我們就可以在Game1.Draw()方法中將Sprite Sheets中的目標小圖片的那塊區域繪制出來。你 應該還記得上一篇文章中講到的Game1.Draw()方法的第三個參數sourceRectangle,用它可以指定我們 要繪制Sprite Sheets的目標區域。

看來,實現一個動畫並非難事,真正困難的地方在於如何控制每個動畫可以有自己不同的刷新速度, 如何使同一個動畫在不同配置的機器上表現相同。這就涉及到幀率問題。

所謂幀率Frame Rate,指的是一秒鐘內重新繪制屏幕的次數。XNA框架為我們設置的默認幀率是60fps 。為什麼選擇60了?因為這是在人的眼睛感覺不到閃爍的情況下顯示器最低的刷新頻率。我們可以通過基 類Microsoft.Xna.Framework.Game的屬性TargetElapsedTime來重新設置它。比如:

base.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 10);

這表示每隔10ms就重繪一次,即幀率為100fps。

設置幀率為100fps,並不表示就真的會達到100fps的速度,這要看機器的配置如何。當機器的配置不 夠時,XNA會自動跳過某些次繪制——即不調用Game1.Draw()方法。我們可以通過GameTime(你還記得 Update和Draw方法都有一個該類型的參數)的IsRunningSlowly屬性來檢測實際的幀率是否比我們設定的 要小。

通過修改TargetElapsedTime屬性來設置幀率,會使所有的動畫都受到影響,因為它實際修改的是調用 Game1.Update()和Game1.Draw()的頻率。

我們如何使一個動畫以自己恆定的速度刷新了?包括這個動畫的刷新速度不受主幀率(即 TargetElapsedTime設定的值)和機器配置的影響,當然,前提條件是我們動畫的刷新率不能大於主幀率 ,也不能超出機器配置允許的最大幀率。

我們可以用類似下面的代碼來控制每個動畫以自己的刷新率運行:

//成員變量

          int timeSinceLastFrame = 0; 

          int millisecondsPerFrame = 50; // 20fps

          //在Update方法中

          timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
          if (timeSinceLastFrame > millisecondsPerFrame) //滿足了換幀條件
          {
                timeSinceLastFrame -= millisecondsPerFrame;

                //...... 此處可以轉到動畫的下一幀

}

通過上述代碼,我們就可以控制目標Sprite的動畫速率為20fps。

在實際的應用中,我們可以將上述控制幀率的代碼放到Sprite的基類中,這樣就可以控制不同的 Sprite以各自的速率運行了。

今天就講到這裡,下一節我們將講述如何捕捉用戶的輸入事件,比如鼠標、鍵盤的輸入。

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