網路遊戲程式中解決載入卡頓的有效方法

2021-08-27 09:21:00 字數 1991 閱讀 8270

這裡要講一下遊戲幀率的控制,通常玩家在玩遊戲抱怨遊戲客戶端卡有兩個意思,一是遊戲平均幀率很低,二是遊戲的幀率非常不穩,導致了卡頓。實際上遊戲平均幀率低,對玩家心情的影響遠不及卡頓造成的影響。平均10幀的遊戲,雖然已經很糟糕了,但是依然能玩,但是頻繁的卡頓給人的感覺就糟糕透了,平時40幀左右的遊戲忽然因為載入個什麼東西卡了一下,幀率掉到了零點幾,然後又恢復到40幀,這種卡頓給人的感覺就是煩透了。

遊戲引擎首要解決的效能問題就是卡頓的問題。要解決卡頓的話需要做到以下兩點:

第一,不要在主線程去載入資源,最忌諱的操作就是開啟檔案,這個操作會掛起當前執行緒,也就是說會讓渲染執行緒停頓。把所有的資源載入操作全放在載入執行緒去做,畢竟載入執行緒隨便停頓也沒什麼關係,對主線程的渲染沒影響,主線程只需要每幀判斷資源是否已經載入上來就可以了。一但發現已經載入上來了,就可以用這個資料去渲染了。

第二,也是最重要的一點,把載入的操作攤到多幀去做。通常角色走進人堆裡以後,或者在戰場上魔法漫天飛的時候,伺服器會傳來大量訊息需要處理,最典型的就是建立訊息,無論是建立角色還建立特效,就算是採用多執行緒載入的方式,在一幀內建立物件,通知執行緒載入底層資源,那麼多訊息的處理依然會不可避免地造成卡頓。這裡有乙個非常好的解決辦法,就是這些處理訊息的操作不要一幀內做完,而是分攤到多幀完成。

一般說來,處理網路訊息的過程是這樣乙個迴圈:

while(訊息佇列中還有訊息)

在一幀當中,迴圈遍歷整個訊息佇列,將這一幀收到的訊息乙個乙個處理一遍。

這樣做忽略了最重要的效率問題,當你因為遊戲卡頓在焦頭爛額地優化資源載入時,不放考慮修改一下訊息佇列的處理。

在這裡,我可以加入計時:gettickcount()

初始時間=gettickcount();

while(訊息佇列中還有訊息)

}如果這一幀的處理時間超過了20ms,則把剩下的訊息放到下一幀處理。通過這種計時的方式,你會發現遊戲的流暢度簡直有了天翻地覆的變化!在優化之前,有個幾個人在用群攻魔法攻擊大量的怪物,這些傢伙忽然湧入到視野中,幀率便一下掉到了零點幾,遊戲出現了非常嚴重的卡頓,這種狀態持續了很短一段時間,幀率又迅速回公升上去。而現在,經過修改以後,你會發現那些傢伙很平滑地出現在視野中,沒有一絲的卡頓。如此效果簡直是奇蹟一般,而這一切僅僅是修改了幾行**而已。

現在考慮這麼做所帶來的問題。如果訊息量非常大,而機器又慢,平均幀率又很低的話,那麻煩可就大了:每幀處理的訊息量還沒有收到的訊息量大。這可是個很嚴重的問題,這會讓客戶端的表現與實際情況嚴重脫節。在這裡,就需要有乙個機制,保證訊息在積攢超過一定數量時,能得到及時的處理:

初始時間=gettickcount();

while(訊息佇列中還有訊息)

else}}

這樣就解決了訊息越積攢越多的問題,當訊息越攢越多時,會一次性處理所有的訊息。但這樣也會帶來乙個問題,那就是在幀率比較低的機器上,當需要處理的訊息特別多時會出現週期性的卡頓。卡頓的原因就是那步一次性處理所有訊息的操作。優化的目的就是要避免這樣的卡頓,而對於低端機器來說,這樣的優化不但沒有起到效果,反而加重了卡頓現象。為了彌補這個方法帶來的弊端,就要對那個經過時間20ms做點手腳:

static時間閾值=20;//注意時間閾值是static的

if(訊息佇列中的訊息數量》100)

else

if(時間閾值<20)

時間閾值=20;

if(時間閾值》40)

時間閾值=40;

初始時間=gettickcount();

while(訊息佇列中還有訊息)

else}}

這裡增加了時間閾值這個靜態變數,替代了之前**中的20,使之成為乙個由當前幀訊息包數量決定的乙個可變的值。當前幀訊息包的數量超過乙個值時,就將這個時間閾值加一,否則減一。這麼做的效果就是,訊息包來得越多,每幀用於處理訊息的時間就越長,也就是說訊息處理耗時的比重在逐漸上公升。這樣就能很大程度上降低訊息數量超過上限的可能性。

最差的情況,如果這樣做依然有週期性卡頓的話,這台機器真的就不適合執行這個遊戲了,退一步講,不作這個優化的話,這台機器玩這個遊戲也依然會卡得要命。:)

當然,時間閾值的範圍,和訊息包的數量上限可以調整,以適合於不同的遊戲。

網路遊戲程式中解決載入卡頓的有效方法

這裡要講一下遊戲幀率的控制,通常玩家在玩遊戲抱怨遊戲客戶端卡有兩個意思,一是遊戲平均幀率很低,二是遊戲的幀率非常不穩,導致了卡頓。實際上遊戲平均幀率低,對玩家心情的影響遠不及卡頓造成的影響。平均10幀的遊戲,雖然已經很糟糕了,但是依然能玩,但是頻繁的卡頓給人的感覺就糟糕透了,平時40幀左右的遊戲忽然...

解決 使用cmder進入有Git倉庫卡頓 的方法

原因 cmder會遍歷這個檔案中的git資料夾中的內容,導致卡頓,在操作的時候卡頓會很難受。解決方法 1 先找到cmder安裝目錄中的vendor資料夾 2 vendor資料夾下有clink.lua檔案 3 然後找到git prompt filter 這個函式,修改裡面的邏輯實現即可實現不在遍歷gi...

談談網路遊戲中的延遲解決方案

我們平常玩的很多網路遊戲,比如英雄聯盟 王者榮耀 pubg等,你感覺到卡頓往往不是因為你的網速問題,而是因為網路延時導致的,比如說lol美服的遊戲伺服器在美國,而你在中國的華中地區玩著美服lol,那麼你的延遲可能會在300ms左右,因為網路請求從美國到中國華中地區需要經過很多的路由,這裡面會消耗掉很...