如何讓畫面動起來?
都知道動畫的原理,想想看跑馬燈,在任意時刻把跑馬燈按停,面對眼睛的那附圖,它叫做幀(Frame)。
幀,就是一串兒連貫動畫里的單個截面。
玩兒游戲的人知道,要達到基本流暢的水准,30fps(frame per second)就夠了,達到毫無察覺的流暢,可能要到60fps,那么,界面以30~60次每秒的頻率重繪,畫面不就動起來了?
在本篇文章里,將解釋常見的基礎概念生命周期到底是怎么回事。
要寫一個游戲框架啦,首先,還是對游戲進行建模,從兩個方面進行,一個是游戲的實體結構,一個是游戲的運行流程(也就是生命周期)。
1、結構分析
市面上很多游戲,在切換場景的時候,都會進入一個loading界面,參考這個現象可以推論出,游戲是由一個個場景構成。
(loading界面用於加載資源,無論是啟動游戲時候一次性loading,還是過程中異步loading又或者切換場景時候loading,都屬於加載策略,這里暫不討論。)
有了場景了,就要考慮游戲背景,背景有可能是一份image,也有可能是復雜的動態生成的地形。
除此之外,還有游戲角色,物品等對象。先就這幾個來做個簡單的建模:
想想上一章說過的內容,Scene可以視為復合控件,BgPainter執行Scene的背景繪制,Role和Item都是單一控件。
當調用Scene的繪制方法時,會首先觸發BgPainter的繪制,然后迭代所有的Role和Item,進行繪制。一次繪制方法的調用,視為一幀。
2、流程分析
一個場景從加載到結束的過程,稱之為場景的生命周期。
我把該生命周期划分為以下幾個步驟:
其中,加載、啟動、停止、銷毀,在整個生命周期中,只會執行一次。而繼續態會多次出現(可以考慮是根據幀率來不斷提出繼續請求),主動發起暫停請求的時候,才會進入暫停態。
圖是畫出來了,代碼怎么寫呢?
一般來說,實現生命周期管理,可以使用狀態機模式。
參見如下偽碼:
1 define Scene{ 2 //空白狀態
3 status=NONE; 4 //時鍾頻率
5 frequence=150; 6
7 /** 8 *接收請求並修改狀態和頻率 9 */
10 void performRequest(Request req){ 11 status=req.status; 12 frequence=req.frequence; 13
14 if(isRunning){ 15 //停止循環調用
16 stopInterval(); 17 } 18 //啟動循環調用,執行方式是根據frequence間隔來調用refresh方法
19 startInterval(); 20 } 21
22
23 /** 24 *刷新 25 */
26 void refresh(){ 27 //根據請求類型來決定執行
28 switch(status){ 29 case LOADING: 30 if(loaded) 31 status=START; 32 else if(!loading) 33 onLoading(); 34 break; 35 case START: 36 if(started) 37 status=RESUME; 38 else if(!starting) 39 onStart(); 40 break; 41 case RESUME: 42 resume(); 43 break; 44 case PAUSE: 45 if(!paused) 46 pause(); 47 break; 48 case STOP: 49 if(!stopped&&!stopping) 50 stop(); 51 break; 52 case DESTROY: 53 if(stopped&&!destroyed) 54 destroy(); 55 break; 56 } 57 } 58 void loading(){ 59 loading=true; 60 //加載loading頁,加載完成后回調
61 loading=false,loaded=true; 62 } 63 void resume(){ 64 //繪制地圖 65 //繪制所有角色 66 //繪制所有物品
67 } 68 }
這段狀態機實現保證了幾點:
1、loading、start、stop三個狀態,無論出現多少次,都只會執行對應函數一次。
2、loading、start對應函數執行完成之后,會修改當前場景的狀態,進入下一個步驟。
3、resume、pause狀態,可以隨時切換
啟動方式如下所示
scene.performRequest({status=LOADING,freqence=150});
如果希望暫停,自然也可以使用
scene.performRequest({status=PAUSE,freqence=150});
一個結構簡單的動畫框架就這樣完成了。下一章來講解一個數據分析框架,可以用於各種不同類型的數據格式之間的互相轉化,比如Json<->java實例,xml<->java實例,或者xml<->Json