理想的狀態(tài)是,將游戲控制在60幀,這樣充分利用顯示器的能力,為用戶提供流暢的畫面。但是,通常情況下還是比較困難的,隨著游戲邏輯的復(fù)雜性,幀率一般情況下都會下降。如果可以有一種可視化的方法,幫助開發(fā)者去觀察每次RequestAnimationFrame的執(zhí)行時間,可以讓開發(fā)者及時的發(fā)現(xiàn)一些耗時的操作,盡量保證每次RequestAnimationFrame的執(zhí)行時間控制在16ms內(nèi)完成。
雖然目前還沒有發(fā)現(xiàn)同一的方法,但是Chrome提供了abut:tracing的標簽頁,可以輔助開發(fā)者,去一探RequestAnimationFrame的究竟。不過,困難的是,如果想完全讀懂 about:tracing,需要對于chrome的架構(gòu)以及渲染方式非常熟悉,在加上GPU的原因,很難一下子完全理解整個頁面。
這里介紹一個簡單的用法,如下圖,是從我的同事Seth的Blog中復(fù)制的圖片,(如果想了解更多內(nèi)容,可以參考Box2D, Web workers, Better performance),可以注意到,圖中有兩個紅線,紅線之間的間隔是16毫秒,相信很容易想到,這是每幀執(zhí)行的最佳時間。在about:tracing頁面中,雙擊每個方塊,可以放大并出現(xiàn)每個函數(shù)的名字,按G,就可以立即出現(xiàn)兩邊的紅線。里面有個泛藍色的模塊,標志W(wǎng)ebViewImp:animate,它就是負責執(zhí)行RquestAnimationFrame,貌似它的執(zhí)行時間沒有超過16ms,但是不幸的,因為在執(zhí)行完RequestAnimationFrame之后,瀏覽器還對于需要渲染的元素,執(zhí)行組裝和渲染操作,很明顯下圖中的渲染時間,超過了紅線的范圍,也就是超過了16ms,圖形渲染的效率自然會降低到60幀一下。
通過這個例子,可以看出,并不是把RequestAnimationFrame的執(zhí)行時間控制在16ms以內(nèi),就可以得到60幀率的渲染。還需要整體考慮,RequstAnimationFrame引起了多少元素的渲染,以及多大程度的重繪。
about:tracing是非常好用的頁面,有更多興趣的同學,還請耐心學習chrome的渲染方式:
Trace Event Profiling Tool (about:tracing)
4) 頁面顯示API
RequestAnimationFrame很重要的優(yōu)點,就是在Tab沒有被顯示的時候,可以暫停執(zhí)行,不消耗CPU資源。對于大部分的動畫需求,是沒有問題的,但是也不能適應(yīng)于所有的場景,舉個例子,現(xiàn)在很多攻防類的游戲,在進攻其他家城堡的時候,可以派兵進行打仗。兩軍對陣的場景,通常是一段設(shè)計好的動畫,有時候動畫的時間還比較長,很多玩家會切換到其他頁面,用戶的本意是在其他網(wǎng)頁等待對戰(zhàn)結(jié)束。而RequestAnimationFrame控制的動畫循環(huán),會因為切換到其他頁面,暫停執(zhí)行,從而違背了設(shè)計的初衷,也違背用戶的一些習慣??梢詮某绦蜻壿嬌媳荛_這個問題,比如人為加入一些計時器,按照時間播放相關(guān)的動畫,但是這樣容易和主程序的循環(huán)出現(xiàn)邏輯上的混亂。幸運的是,HTML5提供了Page Visibility的API。這個API可以在Tab被切換的時候,產(chǎn)生一定的回調(diào),從而可以讓開發(fā)者明確知道,目前頁面處于哪種顯示的狀態(tài)。
- function handleVisibilityChange() {
- if (document.webkitHidden) {
- if (playAnimation is true)
- //continue to do this animation
- }
- }
- document.addEventListener(“webkitvisibilitychange”, handleVisibilityChange, false);
上面是一段簡單的代碼,在發(fā)現(xiàn)頁面不被顯示的時候,可以執(zhí)行一些必須被執(zhí)行的動畫。
5) Webworker的作用
現(xiàn)在很多的游戲,都利用到了Box2d或者其他重力引擎,而這種重力引擎的計算,相當耗費時間,如果將這些計算放在RequestAnimationFrame里面,很容易就會將每次執(zhí)行的時間,超過16ms。最好可以將這類高成本的計算,放在一個單獨的線程,每次RequestAnimationFrame只需要取到結(jié)果就可以了。
HTML5的webworker,剛好可以承擔這個角色。如上圖,是一個簡單的設(shè)計圖,box2d重力引擎,作為獨立計算的單元,存在于webworker內(nèi)部,利用setTimeout作為循環(huán)控制。在外部,RequestAnimationFrame控制動畫的顯示。
具體的代碼和例子,可以參考:Box2D and Web workers for JavaScript developers
6) 毫秒精度的用處
RequestAnimationFrame最近剛推出了新的功能,可以提供微妙級別的精度,這個有什么用處呢?按照前面的說法,每秒60幀的顯示,每幀的具體時間為(1000毫秒/60),大約為16.67毫秒。如果只有毫米級別的精度,為了有效的控制RequestAnimationFrame的執(zhí)行時間,只能以整毫秒的精度,對RequestAnimationFrame進行檢查,也就說,假設(shè)RequestAnimationFrame計劃在5.5毫秒后執(zhí)行,如果執(zhí)行到某一步,發(fā)現(xiàn)當前時間已經(jīng)是5毫秒,雖然理論上也許還有0.5毫秒的時間可以使用,但是不能在進行下一步的。現(xiàn)在有了微秒級別的精度,可以做更精細的控制。下圖的解釋比較形象,上面是16.667每幀可以執(zhí)行的時間,下面是整毫秒數(shù)標志的時間,顯然下面的圖,會浪費很多的時間片。
目前,在chrome中,是通過window.performance.webkitNow()獲得高精度的時間的,相信不久的將來,很快就會變成標準performance.now()。
(未完待續(xù))
接上文:
HTML5游戲開發(fā) 之 循環(huán)的控制(1)
HTML5 游戲開發(fā) 之 資源加載篇(2)
HTML5 游戲開發(fā) 之 資源加載篇(1)
【網(wǎng)站聲明】本站除付費源碼經(jīng)過測試外,其他素材未做測試,不保證完整性,網(wǎng)站上部分源碼僅限學習交流,請勿用于商業(yè)用途。如損害你的權(quán)益請聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。