淺析Flash遊戲架構

先談前端主架構,前端程序主架構有兩個主要任務:


1,要從架構高度合理劃分前端各模塊,提出可行的實現方案;

2,從AS級別搭建程序架構(非文檔級別),制定前端編程規則和接口,規範程序各部分的職責劃分。這兩個任務其實包括不少具體工做,好比:遊戲啓動流程制定,肯定哪些SWF文件須要外部加載,那些功能能夠從主程序剝離出去單獨實現,前端配置文件怎麼處理,公共素材怎麼處理,MVC三層怎麼劃分,主程序框架的選定,主程序怎麼和後臺通信,主程序如何與模塊協做,哪些代碼應該放在主程序中,哪些代碼應該放在模塊裏,主程序如何既能提供模塊所須要的一切功能和數據,同時又相對模塊自我保護等等等等。其實我談的還只是一些大的方面,具體到實現的級別,還有大量細節工做要作。而這些工做在項目啓動之初都是很是重要的,直接影響到項目中後期的開發和維護效率。

上面提到的那些點,我不可能全講一遍,否則就不叫「淺談FLASH WEB GAME」了!我只挑兩個比較核心的內容跟你們略作探討,就是前端AS框架和模塊劃分的問題。先談前端框架:如今市面上流行不少前端框架,無論是針對「FLASH」的,「FLEX」的仍是「通用的」都有。咱們是否必定須要框架,或者必須使用某個框架,這徹底是仁者見仁智者見智的事,從最終的結果上講,爭論這個問題意義不大,我相信一個5W行左右的項目,任何有5年以上編程經驗的人,無論用什麼做戰策略,最終都能攻下山頭,把項目作出來。但有一點相當重要:你必須能徹底把握你的架構和你使用的框架,並能跟你的前端同事解釋清楚。那好壞架構的區別在哪裏呢?區別在於好的架構在開發過程當中會更輕鬆,你不用每天擔憂的你代碼,不用天天不停的寫文檔,以防止本身忘了複雜的邏輯,你能夠在任什麼時候間開始寫代碼,在任什麼時候間去玩會兒遊戲而後回來接着寫;區別在於好的架構更符合業界標準,更容易被傳統和正統的程序員接受理解;區別在於你能夠用很簡單的幾句話就把你的架構思想描述清楚,用幾個很簡單的文檔就能讓別人接手你的代碼,在人事變更和工做交接的時候讓本身更輕鬆;區別在於當你掌握了一種通用框架或者本身總結一套成熟的架構後,你幾乎能夠套用之後的大部分項目,並不斷完善它,開發愈來愈輕鬆,速度卻愈來愈快!

咱們的項目,主程序使用的是pureMVC框架,而主UI部分是本身寫的。主程序和主UI相互獨立,能夠單獨編譯測試。主程序是純代碼,用FLEX SDK編譯,而主UI則是界面和AS混寫並用FLASH編譯。這樣就把MVC中的V從物理層面上徹底獨立了。


pureMVC框架正如其名字,是一款「純粹」的MVC框架,在我看來,他只是幫咱們實現了MVC的編程思想和套路,其它多餘的功能一點沒有,這使它具備更高的通用性,也是它最可愛的地方。根據咱們的經驗,pureMVC單核心版就已經徹底能夠應對主程序有效代碼在10W行如下的項目了。但在我跟不少沒有用過框架的前端朋友聊天中,發現他們對這些框架自己就有抵觸心理,或者有些對MVC模式都理解的不深入,用起MVC框架又怎能駕輕就熟?還有一些更過度的朋友把本身的問題也歸結到框架上,說什麼用了pureMVC框架後,本身的項目編譯一下要十幾分鍾,我聽了以後啼笑皆非,項目編譯慢通常是由於沒有合理劃分模塊致使主程序過大才致使的,跟框架有什麼關係?若是由於你們的種種誤解和這些人的言論而致使一些新人錯過學習這麼一款優秀的框架,我以爲實爲憾事!

pureMVC既然是一種MVC框架,這就意味着你首先要熟悉MVC。這種熟悉絕對不是對MVC的直譯:模型、視圖、控制器,而是要真正理解爲何要把程序劃分紅這幾部分,在劃分主程序模塊時,要時刻能站在MVC的角度考慮問題,而當面對一段實際的代碼時,能快速準確的判斷,這段代碼應該放在MVC中的哪部分。《pureMVC最佳實踐》這份短短几十頁的文檔中,能夠說到處閃爍着MVC的思想火花,不但清楚地闡述了怎麼使用框架,並且時刻從MVC的角度告訴咱們應該把哪些邏輯放在哪些部分中,應該注意什麼問題。這個文檔早已經有中文版,有興趣的朋友能夠本身去看看,文中有的,我這裏就不贅述了。我只結合本身的體驗談一些文中可能沒有涉及的,也是在真正開發中纔會碰到的問題。

1,模型部分在實際開發中除了存儲數據,還有其餘做用麼?是的,其實它的實際職責很是多。它要給Command和Mediator提供接口,響應用戶操做,進行數據操做或者請求遠程數據服務,進行數據的序列化和反序列化,獲得異步數據後可能還要檢查數據合法化。但無論怎麼樣,它始終是在和數據打交道,同時也應該是你的主程序中惟一能夠直接和數據打交道的管道,別的部分要想和數據有接觸,首先要問問它贊成不一樣意。模型處理完數據會以Notification的消息方式通知Command或者Mediator。但絕對不能在Proxy中直接調用Mediator,這是爲了保證數據層的獨立性、可移植性和重用性,也簡化了你的架構思想。不過可移植性這個優點,估計不少搞FLASH WEB GAME的朋友暫時都沒啥機會體驗,呵呵。‘

2,Command,Command,Command!連叫三聲「Command」,但願能夠引發你們的注意。由於Command的使用,在很大程度上反映着你對pureMVC框架的理解,甚至是對MVC模式的理解深度。在pureMVC框架中,各部分通信是用Notification消息,Proxy能夠給Command和Mediator發消息,Command能夠給Command和Mediator發消息,Mediator能夠給Command和Mediator發消息,怎麼樣?你如今是否是點暈了,這是正常的,其實我也有點暈!當你代碼寫到必定規模後,你會更暈。其實pureMVC框架這麼設計原本是爲了讓MVC各部分儘可能脫耦,但這帶來一個負面狀況就是消息發送與接收機制設計的太靈活了,靈活對小項目是好事,但對大項目來講,每每意味着混亂,甚至會致使災難。那怎麼辦呢?只能靠咱們的自覺性自我約束,簡化架構思想了。根據《pureMVC最佳實踐》中的建議,個人作法是這樣的,儘可能使用Command,讓Command成爲Mediator與Proxy之間通信的惟一橋樑,Mediator和Proxy中發出的Notification,接收者必定是某個Command,而後再由Command處理並將結果轉發給真正的消息接收者,Command就算僅僅起一個轉發做用,僅僅有不到10行代碼,也要建立一個Command類。這樣不只使你的架構更加清晰,並且也更符合MVC思想,Command類的大量存在還使你架構的業務邏輯具備了更好的封裝性和擴展性,可謂是一箭三雕,何樂而不爲?惟一的負面影響多是你須要建立和維護更多的Command類文件,但相對於優點而言,這點影響不算啥。

3,我知道如今可能還有一些朋友在用FLASH IDE寫代碼,這些朋友的執着讓人欽佩,但我想任何一個熟練使用過FLEX BUDIER、FD或者FDT的朋友,都毫不會再回頭使用FLASH IDE寫代碼了。——不對啊?不是談pureMVC的麼?怎麼扯到IDE上去了?這是由於我如今要討論的問題就和IDE有關,假如你如今用的仍是FLASH IDE的話,除了隨時寫文檔外,我真的很難想出一個很好的方案可讓你在沒文檔支撐的狀況下,輕鬆掌握和隨時維護幾萬行代碼。可若是你使用的是FDT,就能夠在沒有文檔的狀況下,利用「ctrl + r」和「ctrl + 鼠標左鍵」,以及全文件搜索等工具,瞬間搞清楚代碼之間的聯繫和邏輯,找出要修改的地方。OK,終於到pureMVC了。若是你使用的是FDT,而且開始嘗試使用pureMVC框架,可在使用的過程當中,你發現你在寫主程序時,仍是不停的使用「ctrl + 鼠標左鍵」,而不是「ctrl + r」,這說明你必須從新審視你對pureMVC框架的理解了,請審查你的Mediator類,看裏面是否是充斥着大量的public方法,若是你的對象之間依舊是經過public方法進行引用,而不是經過Notification通信的,那你也沒有必要繼續使用pureMVC框架了。

4,單例模式影響到底有多大?pureMVC是一個徹底依賴單例模式的框架。單例模式彷佛在AS界一直有很大爭議,這樣的話,pureMVC確定也會有相應的爭議了。持反對意見的人,大多集中在「性能」和「團隊協做」方面,他們認爲一個單例持有過多引用會帶來性能問題,並且生怕在團隊協做中本身的單例類被人無心修改,引起離奇的BUG。性能方面,我以前也沒作過10W以上的項目,不敢妄言,但10W行如下的項目,絕對沒有問題,若是你兩三萬行的架構就開始碰到主架構性能問題,估計十有八九是本身的代碼寫的有問題;團隊協做方面,我以爲pureMVC的Fa?ade模式是很是靈活好用的,你們能夠略作討論,制定一個簡單的規則,好比模塊只能經過fa?ade獲取數據和發送Notification,不能直接調用主程序其餘CLASS,只要架構程序員不犯錯,模塊程序員甚至連犯錯的機會都沒有,若是他們有,仍是你的架構思路有問題,請繼續審視本身的代碼。反正單例模式的問題究竟是什麼,我到如今也沒徹底搞懂,主要是咱們的項目沒碰到過此類問題,但願碰到過的朋友能再仔細跟火山說說,我也好弄清楚問題到底出在哪裏了,本身之後能夠更好的避免此類問題發生。

額,框架部分先談上面4點吧,趕快進入下一個話題,模塊劃分:模塊劃分主要包括「核心模塊劃分」和「子模塊劃分」。核心模塊的劃分思路是這樣的:它們是遊戲啓動所必須的,相互之間是緊密聯繫的,還要常常的被子模塊調用;而相對的,子模塊的劃分思路是:他們在遊戲啓動過程當中不是必須的,能夠在遊戲過程當中再加載,子模塊相互之間基本上徹底沒有聯繫,一個子模塊的增長和刪除不會影響到任何其餘子模塊,子模塊可能須要調用主程序的接口或者得到主程序的數據,但主程序絕對不該該依賴某個子模塊。

明確了模塊劃分思路再具體看看哪些部分應該劃分爲核心模塊,哪些部分應該劃分爲子模塊。通常狀況下,核心模塊按照遊戲啓動順序包括:一個殼子SWF → 配置文件包 → 登陸註冊SWF → 主程序SWF → 主UI的SWF → 公共素材包。而子模塊相對來講簡單不少,好比具體的某個小遊戲,某個場景,以及某個場景裏的觸發功能等等。下面我對核心模塊逐一略作解釋。「一個殼子SWF」:這是一個體積很小,但意義很大的SWF;它後面老是跟着隨機變量,確保每次用戶加載的都是最新的;它裏面定義着一些須要常常更新並且每次更新都必須保證用戶也在第一時間就獲得最新值的變量;它裏面最好有一個簡單背景圖,保證用戶在超低網速的時候輸入遊戲網址不至於長時間面對一片空白;它裏面有安全策略的設定,是咱們遊戲和不少第三方平臺合做的基石;它裏面還定義着主程序被加載進來以前的遊戲啓動流程等等。「配置文件包」:核心模塊版本號啊,全局文字說明啊,service接口定義啊,各個核心模塊須要的配置信息啊什麼的,通常是一些XML文件。「登陸註冊SWF」:這個簡單,在加載重量級的SWF前,先加載登陸註冊SWF,能夠保證用戶第一時間就能打開登陸註冊界面,並且能夠有效節省服務器帶寬。「主程序SWF」:這個就是我前面費了好大勁講的主程序部分了。「主UI」:主程序和主UI爲何要分開兩個SWF,我前面已經提過了,後面還有說明,這裏暫時不講。「公共素材包」:公共素材包是一個遊戲不可缺乏,但也不能過度依賴的東西。它包括一些全局的道具和效果,好比表情、技能特效、場景傳送門等等。公共素材包裏面最好就是一些簡單的動畫,體積小功能簡單,嚴禁在公共素材包裏添加上百K的東西,或者代碼上百行的小模塊,公共素材包建議500K如下。

看了上面的講解,你能夠能以爲核心模塊分那麼多,太麻煩了。不錯,在我看來,對SWF加載流程的分解和控制,對異步程序的掌控正是衡量一個AS程序員是否經驗豐富,是否足夠老道的重要指標,不少從其它語言轉到AS並有多年編程經驗的朋友,架構方面可能和AS程序員差很少,甚至比不少自學成才的AS程序員作的更好,但這方面每每不如長期與CPU和SWF體積搏鬥的老牌AS程序員。核心模塊劃分的越合理,用戶體驗每每越好,後期編寫和維護代碼的效率會越高,但在前期會比較麻煩,並且對架構師的架構經驗和能力必須提出更高的要求。什麼都不分,主程序、素材、核心模塊都弄在一個SWF裏,用戶一開始必須先下載完這個SWF,或者弄了一堆核心模塊和超多公共素材,用戶一開始必須面對loading條不停的周而復始,必須等全部核心要素所有加載完成才能進行一些基本操做的作法,從架構角度上講,是最簡單的作法,由於不用過多考慮複雜的異步和SWF拆分問題,但從用戶體驗和長遠的開發維護上講是很是不利的。根據咱們的經驗,用戶登陸前加載的全部資源體積應該控制在200K左右,而用戶進入遊戲主場景前,加載的資源總數應該控制在1M左右。還有前面提到過的那位用了pureMVC後項目編譯一下要十幾分鐘的朋友,估計就是把全部東西都弄到一個SWF裏的作法。主程序隨便改動測試一下,就要十幾分鍾,牽一髮而動全身,開發效率從何談起?根據咱們的經驗,任何主程序、核心模塊還有子模塊的編譯,都必須在10秒之內,這纔是合理的——個人機器是07年花了3000多買的戴爾品牌機。

→談完主架構,接着談主UI。主UI通常指主要的人機交互界面,這裏的主UI區分於主架構中的mediator,當你看過pureMVC文檔後,你就知道了,mediator只不過起到一個真正的V和pureMVC框架之間的橋樑做用,pureMVC裏的mediator其實並不實現什麼功能,真正的功能都是在主UI裏實現的。但主UI又不得不算是主程序的組成部分,由於它不像其餘模塊,基本上只須要調用主程序的接口就好了,自己並不須要對主程序提供接口。而主UI做爲用戶操做界面,必須大量的向主程序的mediator提供接口,或者發送events。因此主程序和主UI之間的配合必須很是密切才行。

不一樣的遊戲類型,能夠選擇的UI解決方案也不一樣。策略類很是適合用FLEX;MMORPG這類標準網遊,很是適合用ASWING;而像咱們海底世界這類遊戲界面很是誇張,沒什麼標準規則,又不是太複雜的界面,仍是適合本身開發。相信任何有過遊戲項目經驗的人都應該能理解,UI也是FLASH開發中的重頭戲,不少細節的處理很是麻煩,在項目早期具備很大的工做量。仍是以咱們的項目爲例,咱們的UI架構思路是這樣的:

1,全部的界面組件都是直接拖放在stage上的,其功能代碼大部分都是在發佈時編譯的,基本上不用new的方式。這種方式的好處是方便編輯界面,從整體上直觀的把握全部的UI,減輕程序運行時的負擔,同時避免addToStage帶來的諸多問題。缺點是,當UI膨脹到必定規模時,可能會須要你有一臺配置比較好的電腦——哎,說到這裏我就傷心啊,我那臺玩魔獸效果全關還卡的電腦,一直陪伴個人整個UI開發歷程。

2,UI的FLA層次結構是這樣的:第一層是文檔類或者與UI主類關聯的某個MC,咱們選用的是MC的方式,由於MC的方式更靈活;第二層是這個MC裏的全部組件,這些組件大部分是根據功能劃分在一塊兒的一組元件,好比你的我的面板,而這個組件自己也是個MC;第三層是組件裏的全部元件或者共用組件,元件就是背景啊,按鈕啊什麼的,而共用組件好比滾動條啊翻頁組件啊什麼的;主要的就這三層,其實那些共用組件MC再往裏面雙擊還能夠劃分一層。對應FLA的層次結構,AS的結構以下:文檔類或者主MC關聯的類是第一層,這個類裏持有全部的界面元件的引用;第二層是這些界面元件對應的組件CLASS,組件的功能都是在這裏實現的,好比我的面板的MC將會對應一個MyPanel的CLASS,這個CLASS裏實現MyPanel的全部功能。至於CLASS和元件之間是怎麼對應的,我用的是一種鬆耦合的代理模式,也就是將MyPanel對應的MC做爲參數傳遞給MyPanel這個CLASS,而這個CLASS會有本身的私有變量記錄對應MC裏須要進行操做的元件,具體到功能實現時,從代碼層面上看,就好像CLASS操做的都是本身的私有變量,而不是直接操做界面元件,這樣,當界面元件修更名字時,CLASS的改動很小。並且這種代理模式能夠實現一個CLASS代理不一樣的元件,當界面只是須要修改外觀,不須要修改功能時,很是方便。那麼這些CLASS是在哪裏初始化並得到它要代理的MC呢?正是在主MC對應的UI主類中,好比當得到MyPanel對應的MC後,就會馬上public var myPanel:MyPanel = new MyPanel(myPanel_mc);當全部的組件註冊完成後,這個UI主類就持有了全部組件的引用,能夠方便主程序調用;代碼的第三層其實就是共用組件,比較特殊的是,個人共用組件,好比滾動條,也是用代理模式寫的。

3,徹底代理模式爲咱們創造了一種可能,就是把UI和UI對應的代碼分開編譯。這跟FLEX的皮膚更換機制有殊途同歸之妙,只不過它的組件是要new出來的,佈局是要代碼控制的,皮膚都是一個個CLASS,總體效果通常都要編譯後才能看出來;而個人組件是直接拖到舞臺上的,佈局大部分是直接在FLASH IDE裏手動佈置好的,皮膚都是一個個命名過的MC,總體效果編譯以前基本上就能看出來。FLEX在更換皮膚的時候,CLASS名絕對不能變,而個人UI在更換皮膚時,MC的名字和層次結構不能變。FLEX關聯皮膚是在編譯時完成的,而個人UI關聯皮膚是在運行時,當啓動程序加載完UI代碼的SWF和皮膚的SWF後,動態指定的。把皮膚和功能代碼分開編譯成兩個SWF有個好處,就是在實際開發過程當中,咱們會碰到有時候只須要修改代碼,而有時候只須要修改界面的狀況,固然,就算你把代碼和界面一塊兒編譯成一個SWF文件了,也徹底能夠對應這種狀況,無非是編譯一次的時間稍微長了一點點。可當你面對這樣的狀況呢:某次遊戲版本更新出現情況,須要你目前功能不變,但畫面必須退回到上一個版本。這時候你傻眼了吧?你開始對策劃們咆哮:「大家能不能想一想好再讓咱們作啊?」但你仍是不得不從新打開已經作好的UI,把裏面最新的界面再修改回老版本,同時還不敢把最新的刪了,由於下一個版本估計立刻又要替換回最新的畫面了。可若是你的皮膚和代碼是分開編譯成兩個SWF的,這種狀況就簡單了,你可讓運維從SVN上拉出上一個版本的皮膚SWF從新發布一下就行了,你所要作的只不過是動一下嘴皮。

4,最後談一下UI的數據層吧,UI是否須要數據層呢?答案是確定的。儘管你能夠從主程序那裏得到任何你想要的數據,儘管大部分時間你只是須要數據來顯示一下而已,但UI本身記住某些數據會大大方便本身寫代碼。UI的數據層不須要主程序那麼複雜,每一個組件有本身的數據變量,而後整個UI再有一個存放公共數據的地方就足夠了。

→談完主程序和主UI,最後再簡單談一下小遊戲、場景和模塊。先說小遊戲吧,小遊戲是相對最獨立的一塊,可能只須要主程序提供用戶數據,並在遊戲結束後將分數發送給主程序就好了。因此這部分從管理的角度上來說是相對輕鬆的,但這不意味着小遊戲開發就簡單了,有時候,麻雀雖小五臟俱全,想開發出一個性能和用戶體驗俱佳的小遊戲絕非朝夕之功,要是碰到一些算法複雜的小遊戲,那就有得頭痛了。其實對於海底世界這類兒童社區遊戲,小遊戲應該走創意和簡單路線,搞得太複雜了,既很差開發,小孩子又不必定玩得來。

相對於小遊戲,場景和模塊就和主程序甚至是主UI關係密切了,但無論怎麼密切,大部分時候它們都是在所要數據,發送事件,或者觸發某個界面的顯示與隱藏。若是某個模塊的修改須要常常波及到主程序,或者不少模塊在作同一件事,重複寫着同一段代碼,這時候就必須從新審視架構,看是否是某些地方架構的不合理了,不合理的地方,只要時機容許,必定要儘快改掉,絕對不能聽任自流,一起小毒瘤最終可能引起癌症。模塊和場景程序員在咱們公司實際上是很是累的,由於每週都須要發佈新的版本,每次都很趕。在這種狀況下,場景和模塊程序員的責任心就很是重要,他們隨便哪裏隨意了一下,會直接致使糟糕的用戶體驗,由於大部分時間,用戶直接接觸的東西都是他們的做品。架構寫的再好,最終模塊都作的很糟糕,對用戶來講沒有任何價值!因此,一個老道的,有責任心的,可以快速開發出優良用戶體驗的AS模塊程序員,徹底有理由拿高薪,由於他們能作到的,一些所謂的純架構師未必作獲得!
相關文章
相關標籤/搜索