2016-03-08 101 views
1

我已經開始使用xna/monogame開發新遊戲。我之前設計了一些2D遊戲,但決定讓這個等距對我來說是新的。我一直在使用reimers等軸瓦引擎教程,其最簡單的大部分繪圖代碼都是這個副本。繪製期間的滾動延遲

當在地圖上滾動時,屏幕上出現一個口吃,我只能描述爲滯後。我已經把一個FPS計數器,並保持在一個堅實的60,所以我認爲這是某種圖形問題。

我已經嘗試過註釋繪圖代碼的各個部分來縮小問題的範圍,但似乎無法取得任何進展,但是幾周前這種情況並沒有發生,所以我相信它已添加了一些東西,可能是問題引起它的瓦片集?

任何建議表示讚賞。我沒有在這裏寫任何代碼,因爲它變成了一個相當大的項目,我不知道哪個領域要專注,但如果有人願意進行調查,我已經上傳了整個項目here

+0

Micky,什麼部分將是有用的?昨天晚上我進行了一些測試,當遊戲第一次啓動時,它似乎變得更糟,並且在滾動一下之後幾乎停止,就好像它在第一次加載紋理時看到它們並且在該點之後正常工作。 – user3208483

+0

在.NET遊戲中出現口吃可能是由於踢入GC引起的。請查看Shawn Hargreaves和Riemer在其各自的XNA博客中的提示。至於啓動滯後,您是否做過任何形式的按需加載資產? – MickyD

+0

謝謝,我會仔細研究一下。沒有我輸入的按需加載,想知道XNA是否自己做,但我確信事實並非如此? – user3208483

回答

3

文藝青年最愛的你正在創建一個新的Texture2D實例(1x1像素)的每次調用DrawMiniMap方法稱爲dummyTexture。這是一個壞主意,因爲紋理需要每次發送到GPU(然後進行處理和收集)。添加一個名爲dummyTexture的字段,並在LoadContent內完全初始化它。

但請閱讀帖子的其餘部分,瞭解如何識別這些問題。

您的Update方法正在以60fps調用,但對於Draw方法也不一定是這樣。因爲默認情況下Game.IsFixedTimeStep設置爲true,所以一旦Monogame發現Draw花費的時間超過預期完成時間,您的Draw方法將跳過幀。

由於您現在編寫遊戲邏輯的方式,這是Monogame確保所有更新都在固定時間步驟中完成的唯一方法。

爲了更好地瞭解發生了什麼,首先爲Draw方法fps創建一組額外的fps變量,並在屏幕上呈現兩個值。你會看到Update是以60 fps的速度繪製的,但是Draw低於此值。

protected override void Draw(GameTime gameTime) 
{ 
    // similar to what you have inside `Update` 
    drawFpsTimer += gameTime.ElapsedGameTime; 
    drawFpsCount++; 
    if (drawFpsTimer >= TimeSpan.FromSeconds(1)) 
    { drawFpsTimer = TimeSpan.FromSeconds(0); drawFps = drawFpsCount; drawFpsCount = 0; } 

    ... 

有了這個地方很容易找準問題的方法內Draw,並得到你的FPS回到60

此外,通過設置IsFixedTimeStepfalse,你可以同時獲得UpdateDraw被稱爲在繼承,但是你Update幀速率會降得很 - 這意味着你應該改變你的所有更新邏輯使用gameTime.ElapsedGameTime而不是假設固定的步驟:

protected override void Initialize() 
{ 
    // use variable time step 
    this.IsFixedTimeStep = false; 
    this.TargetElapsedTime = TimeSpan.FromSeconds(1/60.0); 
    this.graphics.SynchronizeWithVerticalRetrace = true; 

    ... 

我更喜歡所有項目中的可變時間步長,特別是當您發現XNA sometimes takes up 100% CPU time on one core when the default value of Game.IsFixedTimeStep is used,但是準備好進行一些重構時。

至於爲什麼框架正在跳過,它似乎是DrawMiniMap方法是有問題的。對此進行評論可以在我的機器上獲得60 fps更新+ 60 fps的提取率。

經進一步檢查,原來你正在創建一個新的Texture2D實例(1x1像素)呼籲dummyTexture每次調用此方法。這是一個壞主意。添加一個名爲dummyTexture的字段,並在LoadContent內完全初始化它。通過使tileColour成爲Tile類的成員,以避免在每次迭代中進行大量的if測試,但也可能會稍微加快此方法的速度,但可能有許多此類優化,可能不需要,除非您要部署到移動設備。

+0

感謝所有的信息,非常有幫助,我會看看這個。我會注意到小地圖代碼是一個新的加法,並且在那之前我遇到了問題。完全忘記移動虛擬紋理,謝謝提醒! :p – user3208483

+1

真的很好閱讀,並不是每個人都會從標記爲可疑網站的文件下載文件,除了相關文件之外調試/讀取所有文件以撰寫詳細的答案。 – Prix

+0

@ user3218507:好的,這是我在我的機器上看到的。遊戲*對於這樣一個看似簡單的遊戲已經很奇怪了,例如如果我禁用vsync並註釋掉除DrawCursor部分(這是您繪製fps的地方)以外的所有內容,幀速率將降至〜400fps,如預期的那樣。但是,隨着和所有東西的繪製,幀頻接近80fps(vsync禁用),這意味着你沒有太多空間。所以我建議你使用一個探查器,並嘗試找到所有其他瓶頸。 – Groo