青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

3d Game Walkman

3d圖形渲染,網絡引擎 — tonykee's Blog
隨筆 - 45, 文章 - 0, 評論 - 309, 引用 - 0
數據加載中……

轉載—網絡游戲程序中解決加載卡頓的有效方法

對于3d視頻游戲來說,游戲引擎的性能是至關重要的。玩家在體驗一款游戲時,游戲的流暢度是最基本的要求。與單機游戲不同,網絡游戲更需要考慮性能問題,因為無法像單機游戲那樣,控制游戲元素的復雜度來達到效率的要求。大量玩家涌入同一片區域,同屏出現大量的游戲角色是無法避免的,因此游戲幀率的大幅下降,系統資源的大量消耗也很難避免,這是網絡游戲引擎最難處理的問題之一。
    這里要講一下游戲幀率的控制,通常玩家在玩游戲抱怨游戲客戶端卡有兩個意思,一是游戲平均幀率很低,二是游戲的幀率非常不穩,導致了卡頓。實際上游戲平均幀率低,對玩家心情的影響遠不及卡頓造成的影響。平均10幀的游戲,雖然已經很糟糕了,但是依然能玩,但是頻繁的卡頓給人的感覺就糟糕透了,平時40幀左右的游戲忽然因為加載個什么東西卡了一下,幀率掉到了零點幾,然后又恢復到40幀,這種卡頓給人的感覺就是煩透了。
    游戲引擎首要解決的性能問題就是卡頓的問題。要解決卡頓的話需要做到以下兩點:
    第一,不要在主線程去加載資源,最忌諱的操作就是打開文件,這個操作會掛起當前線程,也就是說會讓渲染線程停頓。把所有的資源加載操作全放在加載線程去做,畢竟加載線程隨便停頓也沒什么關系,對主線程的渲染沒影響,主線程只需要每幀判斷資源是否已經加載上來就可以了。一但發現已經加載上來了,就可以用這個數據去渲染了。
    第二,也是最重要的一點,把加載的操作攤到多幀去做。通常角色走進人堆里以后,或者在戰場上魔法漫天飛的時候,服務器會傳來大量消息需要處理,最典型的就是創建消息,無論是創建角色還創建特效,就算是采用多線程加載的方式,在一幀內創建對象,通知線程加載底層資源,那么多消息的處理依然會不可避免地造成卡頓。這里有一個非常好的解決辦法,就是這些處理消息的操作不要一幀內做完,而是分攤到多幀完成。
    一般說來,處理網絡消息的過程是這樣一個循環:
while( 消息隊列中還有消息 )
{
   從隊列中取出第一條消息;
   處理這條消息;
   將這個消息從隊列中刪除;
}
    在一幀當中,循環遍歷整個消息隊列,將這一幀收到的消息一個一個處理一遍。
    這樣做忽略了最重要的效率問題,當你因為游戲卡頓在焦頭爛額地優化資源加載時,不放考慮修改一下消息隊列的處理。
    在這里,我可以加入計時:GetTickCount()

 

初始時間 = GetTickCount();
while( 消息隊列中還有消息 )
{
   從隊列中取出第一條消息;
   處理這條消息;
   當前時間 = GetTickCount();
   經過時間 = 當前時間 - 初始時間;
   if( 經過時間 > 20 )
   {
      break;
   }
}
    如果這一幀的處理時間超過了20ms,則把剩下的消息放到下一幀處理。通過這種計時的方式,你會發現游戲的流暢度簡直有了天翻地覆的變化!在優化之前,有個幾個人在用群攻魔法攻擊大量的怪物,這些家伙忽然涌入到視野中,幀率便一下掉到了零點幾,游戲出現了非常嚴重的卡頓,這種狀態持續了很短一段時間,幀率又迅速回升上去。而現在,經過修改以后,你會發現那些家伙很平滑地出現在視野中,沒有一絲的卡頓。如此效果簡直是奇跡一般,而這一切僅僅是修改了幾行代碼而已。
    現在考慮這么做所帶來的問題。如果消息量非常大,而機器又慢,平均幀率又很低的話,那麻煩可就大了:每幀處理的消息量還沒有收到的消息量大。這可是個很嚴重的問題,這會讓客戶端的表現與實際情況嚴重脫節。在這里,就需要有一個機制,保證消息在積攢超過一定數量時,能得到及時的處理:

初始時間 = GetTickCount();
while( 消息隊列中還有消息 )
{
   if( 消息隊列中的消息數量 > 300 )
   {
      一次性處理所有的消息;
   }
   else
   {
      從隊列中取出第一條消息;
      處理這條消息;
      當前時間 = GetTickCount();
      經過時間 = 當前時間 - 初始時間;
      if( 經過時間 > 20 )
      {
         break;
      }
   }   
}
    這樣就解決了消息越積攢越多的問題,當消息越攢越多時,會一次性處理所有的消息。但這樣也會帶來一個問題,那就是在幀率比較低的機器上,當需要處理的消息特別多時會出現周期性的卡頓。卡頓的原因就是那步一次性處理所有消息的操作。優化的目的就是要避免這樣的卡頓,而對于低端機器來說,這樣的優化不但沒有起到效果,反而加重了卡頓現象。為了彌補這個方法帶來的弊端,就要對那個經過時間20ms做點手腳:

static 時間閾值 = 20;     //注意時間閾值是static的
if( 消息隊列中的消息數量 > 100 )
{
   ++時間閾值;
}
else
{
   --時間閾值;
}
if( 時間閾值 < 20 )
   時間閾值 = 20;
if( 時間閾值 > 40 )
   時間閾值 = 40;

初始時間 = GetTickCount();
while( 消息隊列中還有消息 )
{
   if( 消息隊列中的消息數量 > 300 )
   {
      一次性處理所有的消息;
   }
   else
   {
      從隊列中取出第一條消息;
      處理這條消息;
      當前時間 = GetTickCount();
      經過時間 = 當前時間 - 初始時間;
      if( 經過時間 > 時間閾值 )
      {
         break;
      }
   }   
}
    這里增加了時間閾值這個靜態變量,替代了之前代碼中的20,使之成為一個由當前幀消息包數量決定的一個可變的值。當前幀消息包的數量超過一個值時,就將這個時間閾值加一,否則減一。這么做的效果就是,消息包來得越多,每幀用于處理消息的時間就越長,也就是說消息處理耗時的比重在逐漸上升。這樣就能很大程度上降低消息數量超過上限的可能性。
最差的情況,如果這樣做依然有周期性卡頓的話,這臺機器真的就不適合運行這個游戲了,退一步講,不作這個優化的話,這臺機器玩這個游戲也依然會卡得要命。:)
   當然,時間閾值的范圍,和消息包的數量上限可以調整,以適合于不同的游戲。

posted on 2009-02-28 13:47 李侃 閱讀(1487) 評論(2)  編輯 收藏 引用 所屬分類: 前臺客戶端

評論

# re: 轉載—網絡游戲程序中解決加載卡頓的有效方法  回復  更多評論   

對于分攤到多幀的方案,確實身有體會,記得以前做過一個游戲模板數據查詢的工具,是用MFC做的,由于一次性查找到的數據過多,一下子加載到列表控件中會引起很嚴重的停頓,于是我便學游戲的樣子將其放到多個幀中處理,程序仍然是單線程,但立馬流暢了很多。
2009-08-10 22:01 | 李現民

# re: 轉載—網絡游戲程序中解決加載卡頓的有效方法  回復  更多評論   

嗯,不錯,學習了。
2010-03-10 09:55 | 月隱
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜免费久久久久| 国产一区二区黄色| 猛干欧美女孩| 一区二区三区在线观看欧美| 亚洲人被黑人高潮完整版| 久久久久青草大香线综合精品| 亚洲欧美中日韩| 国产一区二区三区久久悠悠色av| 久久久夜色精品亚洲| 久久精品欧洲| 亚洲精品一品区二品区三品区| 亚洲国产一二三| 欧美午夜精品久久久久久超碰| 欧美一区二区视频网站| 午夜精品福利视频| 亚洲国产视频一区| 日韩视频免费在线| 国产亚洲欧美一区在线观看| 欧美成人在线免费视频| 久久精品国产久精国产思思| 性高湖久久久久久久久| 欧美黄在线观看| 欧美三级视频| 久久夜色精品亚洲噜噜国产mv| 麻豆久久婷婷| 亚洲欧美综合精品久久成人| 久久久久一区二区三区四区| 99国产精品久久久久老师| 亚洲欧美成人一区二区在线电影| 伊人成年综合电影网| 一本一本久久a久久精品综合麻豆| 国产日产精品一区二区三区四区的观看方式 | 免费美女久久99| 欧美日韩视频第一区| 久久精品国产69国产精品亚洲| 免费永久网站黄欧美| 性欧美暴力猛交69hd| 欧美第十八页| 久久亚洲一区| 国产精品区一区二区三| 欧美h视频在线| 国产老肥熟一区二区三区| 亚洲大片av| 国产一区二区三区精品久久久| 亚洲精品在线观| 尤妮丝一区二区裸体视频| 欧美国产视频在线| 欧美黄色aa电影| 韩国成人精品a∨在线观看| 亚洲黄色在线看| 狠狠色狠色综合曰曰| 制服丝袜亚洲播放| 亚洲三级影院| 美女诱惑黄网站一区| 久久看片网站| 国产婷婷97碰碰久久人人蜜臀| 亚洲另类在线一区| 亚洲美女区一区| 免费看的黄色欧美网站| 久久网站免费| 狠狠色丁香婷综合久久| 午夜精品久久久久久久白皮肤 | 欧美在线视频不卡| 欧美日本韩国在线| 国产欧美日本一区二区三区| 久久国产精品久久精品国产| 国产精品高潮呻吟久久av黑人| 亚洲第一福利在线观看| 亚洲高清123| 久久天堂国产精品| 欧美激情视频给我| 亚洲精品一级| 欧美日韩国产小视频| 亚洲精品乱码久久久久久黑人 | 欧美精品在线一区| 亚洲国产日韩欧美在线图片| 亚洲欧洲一二三| 欧美激情视频给我| 亚洲精品日本| 亚洲专区在线视频| 国产精品久久二区| 亚洲欧美在线一区| 麻豆久久精品| 亚洲精一区二区三区| 久久国产精品毛片| 欧美第十八页| 亚洲一二三四区| 欧美大片国产精品| 亚洲成人自拍视频| 欧美成人精品不卡视频在线观看| 欧美激情久久久| 在线亚洲一区观看| 国产日本亚洲高清| 免费久久精品视频| 宅男噜噜噜66一区二区| 久久婷婷蜜乳一本欲蜜臀| 在线视频国产日韩| 欧美色偷偷大香| 久久精品二区亚洲w码| 亚洲高清123| 午夜精品久久久久久久久久久久久| 国产婷婷色一区二区三区| 久久这里只有精品视频首页| 99re亚洲国产精品| 久久青青草综合| 亚洲最新视频在线播放| 欧美国产高清| 亚洲欧美日韩国产中文| 欧美v亚洲v综合ⅴ国产v| 欧美一激情一区二区三区| 精品成人久久| 欧美久久影院| 久久久99爱| 一区二区三区日韩欧美精品| 榴莲视频成人在线观看| 亚洲一区二区三区777| 伊人久久噜噜噜躁狠狠躁 | 亚洲精品欧美极品| 久久久在线视频| 亚洲女女做受ⅹxx高潮| 亚洲精品中文字幕在线观看| 国产亚洲人成a一在线v站| 欧美性猛交xxxx乱大交退制版| 久久免费99精品久久久久久| 亚洲欧美精品伊人久久| 亚洲美女在线一区| 亚洲第一毛片| 久久亚洲免费| 99国产精品国产精品久久| 欧美视频在线播放| 欧美成人黑人xx视频免费观看| 欧美一区1区三区3区公司| 亚洲免费观看| 91久久综合| 欧美激情一区| 欧美a级片网| 开元免费观看欧美电视剧网站| 午夜精品福利一区二区三区av| 中文高清一区| 一区二区三区国产在线| 日韩视频精品在线| 91久久久久久| 亚洲精品一区二区三区福利| 亚洲高清视频的网址| 亚洲第一中文字幕| 亚洲国产精品女人久久久| 国内久久精品视频| 激情欧美日韩一区| 在线观看视频一区二区| 激情成人av在线| 亚洲电影自拍| 亚洲三级电影在线观看| 日韩视频二区| 一区二区三区国产盗摄| 亚洲影音先锋| 亚洲欧洲av一区二区| 欧美一区二区啪啪| 久久久www| 欧美高清在线观看| 亚洲激情社区| 亚洲午夜久久久久久尤物| 亚洲影视综合| 久久久久久久网| 欧美精品xxxxbbbb| 国产精品v欧美精品∨日韩| 国产欧美精品日韩| 激情视频一区| 日韩一级精品视频在线观看| 亚洲在线观看| 久久天天躁狠狠躁夜夜av| 亚洲电影av在线| 亚洲一本大道在线| 久久精品二区| 欧美另类极品videosbest最新版本| 欧美三区美女| 激情视频一区二区| 一本色道久久综合亚洲精品高清| 午夜亚洲精品| 欧美激情女人20p| 一区二区三区|亚洲午夜| 久久成人这里只有精品| 欧美高清视频在线播放| 国产精品视频成人| 亚洲精品国产精品乱码不99按摩| 亚洲一区二区三区高清 | 日韩视频永久免费观看| 亚洲欧美日韩国产另类专区| 美女国产一区| 一区二区三区|亚洲午夜| 久久美女性网| 国产精品视频你懂的| 亚洲日本在线视频观看| 欧美一激情一区二区三区| 亚洲福利国产| 久久都是精品| 国产精品午夜在线观看| 亚洲精品一区二区三区av| 久久久久久网| 午夜精品久久久久影视| 欧美日韩精品一区二区三区四区|