游戲主循環是游戲的心跳,一般使用進行主動刷新。
一次循環由、、、和組成。
這些行為可以分成兩類:
(); 一般不耗時
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個可能的實現方法,其中有一個方案是要堅決避免的,那就是的方案。
恆定的幀率對移動設備而言,可能是一個很好的實現;如果你想展示你的硬件全部的實力,那麼最好使用的實現方案。
如果不想麻煩的實現一個預言函數,那麼可以使用的實現方案,唯一需要考慮的是。