程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 游戲主循環(Game Loop)

游戲主循環(Game Loop)

編輯:C++入門知識

游戲主循環是游戲的心跳,一般使用進行主動刷新。

 

一次循環由、、、和組成。

這些行為可以分成兩類:

(); 一般不耗時

display_game(); 耗時(場景越復雜越耗時)

 

:每秒調用的次數。

:即幀率;每秒調用的次數。

:即顯示幀率,每秒調用且的次數。

 

 game_is_running = 

該循環主要的問題是忽略了時間,游戲會盡情的飛奔,能有多快就運行多快

我們會看到在性能好的機器上,物體運動得更快一些

 

  FRAMES_PER_SECOND =   SKIP_TICKS =  /= GetTickCount(); 
 sleep_time =  game_is_running = +== next_game_tick -( sleep_time >= 

:重新播放游戲會顯得簡單(因為每幀時間間隔固定,只需要記錄下每一幀游戲的狀態,回放時按照25幀的速度播放即可)

:到某些復雜的游戲場景時,繪制會耗費大量時間,影響游戲輸入和AI的響應,游戲會變得很慢(卡)

                            當場景變得簡單時,游戲會加速運行,直到match到正常的步伐,然後穩定到25幀

:對於高速移動的物體,對視覺效果有一些影響(原來可以跑300幀,現在被強制只能運行25幀);另外,由於調用了Sleep,會比較省電一些

:FPS阈值定義得太高會使得配置差的機器機不堪重負,定義得太低則會使得高端硬件損失太多視覺效果

 

= GetTickCount(); 
 game_is_running = == GetTickCount(); 
  update_game( curr_frame_tick -

時需要考慮與的時間差。

:到某些復雜的游戲場景時,繪制會耗費大量時間,影響游戲輸入和AI的響應,游戲會卡頓

                            然而,就會強制match到正常的步伐,這樣我們就會看到一些跳變()

:也可能會出現問題,原因是的調用次數存在差異;越牛逼的機器,update_game的調用次數越多。這種差異引起的浮點數誤差,會導致致命的錯誤

 

  TICKS_PER_SECOND =   SKIP_TICKS =  /  MAX_FRAMESKIP = = GetTickCount();
 game_is_running = = ( GetTickCount() > next_game_tick && loops <+=++

:當渲染幀率下降到5(TICKS_PER_SECOND/MAX_FRAMESKIP)即:loops>=MAX_FRAMESKIP,游戲才會變慢(卡)

                            當場景變得簡單時,游戲會加速運行,直到match到正常的步伐,然後穩定到50幀

:游戲會以穩定的50幀速度更新,渲染速度也盡可能的快;但渲染速度超過了50幀時,有一些幀的畫面將會完全相同,所以顯示FPS實際上也等同於最快50幀

:如果定義過高的FPS阈值,會讓配置差的機器吃不消,過低則會讓牛逼的機器難以發揮性能

 

  TICKS_PER_SECOND =   SKIP_TICKS =  /  MAX_FRAMESKIP = = GetTickCount();
 game_is_running = = ( GetTickCount() > next_game_tick && loops <+=++= ( GetTickCount() + SKIP_TICKS - next_game_tick ) / 

邏輯幀(玩家輸入、AI)本身並不需要很高的速度,25幀就足夠了

渲染則放任不管,任其飛奔;與前面的方案相比,多了一個插值參數,我們需要在裡面實現一個接受插值參數的預言函數

邏輯幀為25幀,如果渲染時不時用插值計算,顯示幀會被限定在25幀。25幀可以很好的展示游戲畫面,不過對於高速的物體,更高的幀率會有更好的效果

所以,我們需要一個讓高速移動的物體在顯示幀之間平滑的過度

游戲狀態更新在一個恆定的幀率下運行著,當你渲染畫面的時刻,很有可能就在兩個邏輯幀之間

假設你已經第10次更新了你的游戲狀態,現在你需要渲染你的場景,這次渲染就會出現在第10次和第11次邏輯幀之間

很有可能出現在第10.3幀的位置。那麼插值的值就是0.3。舉個例子說,一輛賽車以下面的方式計算位置

position = position + speed;

如果第10次邏輯幀後賽車的位置是500,速度是100,那麼第11幀的位置就會是600. 那麼在10.3幀的時候你會在什麼位置渲染你的賽車呢?

顯而易見,應該像下面這樣:

view_position = position + (speed * interpolation)

position=500,speed=100,interpolation = 0.3

現在,賽車將會被正確地渲染在530這個位置。基本上,插值的值就是渲染發生在前一幀和後一幀中的位置。

你需要做的就是寫出預言函數來預計你的賽車/攝像機或者其他物件在渲染時刻的正確位置。

你可以根據物件的速度來計算預計的位置。這些並不復雜。

對於某些預計後的幀中出現的錯誤現象,如某個物體被渲染到了某個物體之中的情況的確會出現。

由於游戲速度恆定在25幀,那麼這種錯誤停留在畫面上的時間極短,難以發現,並無大礙。

:當渲染幀率下降到5(TICKS_PER_SECOND/MAX_FRAMESKIP),此時loops>=MAX_FRAMESKIP,游戲才會變慢

                            當場景變得簡單時,游戲會加速運行,直到match到正常的步伐,然後邏輯幀穩定到25幀

:邏輯幀會保持25幀,插值的方案可以讓游戲在高幀率中有更好的畫面表現。

:最好的游戲主循環實現。不過,必須實現一個插值計算函數

 

討論了4個可能的實現方法,其中有一個方案是要堅決避免的,那就是的方案。

恆定的幀率對移動設備而言,可能是一個很好的實現;如果你想展示你的硬件全部的實力,那麼最好使用的實現方案。

如果不想麻煩的實現一個預言函數,那麼可以使用的實現方案,唯一需要考慮的是。

 

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