2010-05-08 45 views
5

XNA如何保持一致且精確的60 FPS幀速率?另外,它如何保持這樣精確的時序,而不用100%固定CPU?XNA時序如何工作?

+1

我通常想知道任何常規時機如何做到這一點。 – 2010-05-08 22:37:33

回答

2

我不知道具體XNA是怎麼做的,但用OpenGL玩弄時,幾年前,我使用一些非常簡單的代碼來完成同樣的事情。

在它的核心I假設XNA具有某種渲染迴路的,它可以或可以不與一個標準甚至處理循環,但例如起見讓我們假設它不是一體。在這種情況下,你可以寫一些這樣的東西。

TimeSpan FrameInterval = TimeSpan.FromMillis(1000.0/60.0); 
DateTime PrevFrameTime = DateTime.MinValue; 
while(true) 
{ 
    DateTime CurrentFrameTime = DateTime.Now; 
    TimeSpan diff = DateTime.Now - PrevFrameTime; 
    if(diff < FrameInterval) 
    { 
     DrawScene(); 
     PrevFrameTime = CurrentFrameTime; 
    } 
    else 
    { 
     Thread.Sleep(FrameInterval - diff); 
    } 
} 

在現實中,你可能會使用類似Environment.Ticks而不是DateTime是否(這將是更準確),但我認爲這說明了這一點。這應該每秒調用drawScene大約60次,剩下的時間線程將進入休眠狀態,因此不會產生任何CPU時間。

+0

但是通過使用Thread.Sleep,它不依賴於線程調度嗎?充其量,這似乎有點可預見。這就是我想知道他們如何保持一致的原因。 – redman 2010-05-09 03:37:23

+0

使用線程睡眠不會讓你處於調度程序的擺佈之中,但是從長遠來看,它應該相當不錯,特別是在一秒鐘內有60幀之後。當談到計算機上的高精度定時時,無論如何都受到調度程序的支配,因爲您的線程可以隨時換出。 – luke 2010-05-09 03:52:34

0

遊戲應該在60fps運行,但這並不意味着他們會。這實際上是已發佈遊戲的上限。

如果調試模式運行遊戲,你可以得到每秒更高的幀 - 我在調試模式下的筆記本電腦,例如空白起動模板在1,000fps運行良好。

話雖這麼說,在發佈遊戲的XNA框架將盡最大努力在60fps運行 - 但你在你的項目中包含的代碼具有降低,業績的機會。例如有一些不斷觸發垃圾收集,你通常會看到暢遊在遊戲的FPS,或在更新拋出一些複雜的數學或繪製方法 - 從而讓他們開火每frame..which平時就有點過分了。有很多事情需要記住,以儘可能簡化您的遊戲。

如果你問的是XNA框架如何使天花板發生 - 我無法真正解釋 - 但我可以說,這取決於你如何佈局你的代碼 - 你可以做的事情可以肯定會對這個數字產生負面影響,並不總是必須與CPU相關。在垃圾收集的情況下,它只是清理RAM,根本不會顯示CPU使用率的高峯 - 但可能會影響您的FPS,具體取決於垃圾數量和運行時間間隔。

+0

在這個答案中,你錯了很多事情......調試模式導致更多開銷,而不是更少。代碼會降低性能並非「偶然」;它總是會的。垃圾收集總是會影響CPU的週期。 – 2011-07-20 22:13:24

4

雖然上述盧克的代碼是理論正確的使用方法和屬性都不是最好的選擇:

目前XNA FX似乎掛鉤到Windows消息循環並執行其內部的更新前每個步驟只有在自上次更新之後的經過時間與指定的幀速率相匹配(例如,每個默認設置爲16ms)時纔會調用Game.Update。如果你想真正瞭解XNA FX是如何工作的Reflector是你的朋友:)

隨機小知識:回到XNA GameStudio 1。0 Alpha/Beta時間框架有很多關於「完美WinForms遊戲循環」的博客文章,儘管我現在未能找到它們......

0

您可以閱讀關於XNA計時器在這裏如何實現的所有信息Game timing in XNA Game Studio但基本上它如果XNA需要「趕上」,可以在再次繼續循環之前嘗試並在1/60秒內完成,同時請注意,可以在渲染之前多次調用更新。