•不知道有多人跟筆者一樣,喜歡學各種技術,但是都不精,但也有一兩項算是精的。
自從踏上了egret游戲開發的道路,就不得不學習各種技術了,因為,要精通egret,首先必須要會TypeScript,其次是JavaScript,如果只是簡單點的HTML5游戲,那么學這兩樣就可以了。
如果,你想再對web頁面美化一下,你就要學html標記語言還有css樣式,這樣,一款簡單的單機游戲就可以上線了。
如果,你還想加個分數統計、數據采集之類的功能,那你就必須會一門動態網站語言了,php、jsp、asp.net、nodejs-web、golang-web或者其他。
如果,你還想做網絡版的egret游戲,那么,你還要學一門網絡服務器語言,當然,這個選擇是更多了,幾乎每種語言都可以,只要協議支持,比如node.js-socket.io就是很好的websocket框架。
最后一個如果,如果,你想把html5游戲打包成apk或者ipa,那你有兩種途徑,一種是自己寫個app,然后在app里面放一個WebView或者UIWebView,然后指向你的html5游戲發布地址。這種加殼技術最簡單了,如果你還要調用一些特殊的本地api,那么,你可以選擇一下完善點的框架,比如Cordova,里面集成了幾乎所有的可調用的api接口供js調用。
但是這種加殼技術有局限性,因為要依賴於一個webview,也就是要看游戲流不流暢,就要看系統分配給webview的資源多不多了,顯然,一個webview在android系統上的資源真是不夠多,而且,android系統的webview真是不敢恭維,用的的chrome內核的老版本,ios的UIWebView卻是時刻緊跟safari的步伐。如果要解決這個問題,可以自己下載最新的chrome源碼,然后編譯到app中,或者先對其進行優化和刪減。
app打包的另一種途徑,就是native打包了,這種打包機制和webview打包是不一樣的,並不是一個webview就能搞定的,需要解決js解析和渲染、音頻、網絡、交互等所有的之前通過一個webview全部包裝的功能,在egret里,這些都被叫做Context。
這里寫個個人見解:egret並不只是一個html5框架,他實則是一個js框架,框架層面,他調用了上述所說的Context,只是在不同的設備環境上,實現了這些Context定義的接口標准,然后讓js框架去調用。
設想,如果你手上有一只藍屏的老款諾基亞,想在里面運行一個你用egret寫的貪吃蛇(想當年筆者能玩好多分啊!),可以呀,只要你去實現了那幾個Context,就可以了,最關鍵的是,你要把一款js解析引擎搞進去,當然,那時候的手機根本吃不消。
這樣使得開發者可以充分得去利用egret來實現一下天馬行空的創想!
實現這些Context,工作量是很大的,幸好egret研發團隊已經幫你全部解決了:
- js解析引擎>egret采用的是google開源的V8引擎,自稱是最快的js引擎,而egret早期采用的是mozilla的SpiderMonkey引擎,一樣是很優秀的js引擎。
- 渲染Context>渲染上下文肯定是用OpenGL了,在android和ios上都能流暢渲染。
- 音頻Context>直接調用系統的音頻解決方案即可
- 網絡Context>直接調用系統的網絡接口即可
- 交互Context>需要調用android或者ios上的Touch事件
- 其他實現
•到底哪家強
到了這里,你肯定想問egret和業內上很火的Cocos2d-x到底哪個更好呢?那肯定不能說哪個更好,因為各有千秋。
在渲染方面,雖然都采用OpenGL,但是cocos2d-x卻比egret快,為什么呢?因為egret為了抽象出底層的Context,所以把很多東西都交給了js,Context只做了渲染,而cocos2d-x則從頭到腳都是c++寫的,你說哪個渲染更花時間呢!
但是,對於as3開發者的筆者來說egret更加親和,因為egret的各種機制基本上是仿照as3設計的,使得我很快就能從as3轉到egret(我就用過一次Ts轉As代碼的工具,為了看看Ts和As的差異),而后都是直接編寫ts代碼,直接上手。
其實在接觸egret之前我自己動手寫過簡單的html5框架,很簡單的東西,實現了as3的Graphics,內部機制還引以為傲地取名為命令隊列,后來看了別人的框架才知道別人早就這么寫了。。。
后來接觸過一個國人寫的html5框架,基於canvas和dom兩種渲染方式的
“在去年三月份,某人接到了某人的郵件,說有個很隱秘的大案子要不要參與”,當時egret群里看到了這句話。后來那人成了egret的大牛。
但是,egret的開發流真心挺親民的,周邊產品挺多,強大的GUI工具-EgretWing是筆者最喜歡的了,用as3+ane寫的,自身采用的是Dom自己寫的FlexLite框架。還有其他產品比如:引擎管理器、vs開發插件、資源管理器、材質編輯器、粒子系統編輯器、As3轉TS工具、Chrome Inspection插件、龍骨Falsh pro插件(龍骨官方出品)
里面筆者未提及的就是egret-runtime,這是對現有webview的一個插件式優化,egret-runtime其實是把webview中渲染低下的部分用OpenGL來渲染了,這樣能提高幀率從而提升用戶體驗。但是這也有弊端,就是機子發熱嚴重,耗電很快,所以這個要開發者自己去權衡。
設想如果現在主流的android瀏覽器app都內置了egret-runtime,那玩起egret游戲來說,是不是很爽啊,白鷺公司也是蠻拼的,已經談了幾家公司了,只要通過這些app打開egret游戲頁面,都會使用runtime加速渲染。
•最后一個如果
博文開頭說了那么多如果,當然,最后一個如果才是關鍵,egret在實現完Context后,封裝成了Android項目模版和xcode項目模版,以便開發者做native打包app使用。這時候,你就需要會另外兩門語言了:Java和Obejctive-c了,還有就是各自的開發框架:android和cocoa。
筆者在native打包之前稍微學過點android開發,算是有點基礎,能做一些簡單的應用,但是對於oc開發,那真是一無所知了,於是便從頭學起,在win8.1上裝了個vm,虛擬了個mac os,然后開始搞oc開發,打包ipa是ios開發的同事教筆者的(公司不給陪蘋果機嘛,只能這樣啦,噓!)。於是第一款游戲誕生了,Zombie Infect,現已現身Google Play,App Store還在排隊(兩周了居然還在排隊),html5版還未上線,需要等公司的平台出來。
Zombie Infect的三端實現:android、html5、ios
如果接第三方庫呢,先把庫引入項目,然后通過java或者oc去調用,那什么去調用java和oc呢,因為他們不知道什么時候要調用呀,那就是egret提供的ExternalInterface
了,和as3的有點像。他就是js和native開發語言的橋梁了,通過他,我們就可以實現各種本地api的調用而是的游戲更加健全了。筆者封裝了一遍擴展接口,現已實現
- navigateToUrl:用瀏覽器打開網頁,在android和ios上都適配了
- closeApp:關閉app,android有效
- showBanner:顯示admob廣告條
- hideBanner:隱藏admob廣告條
- ShowInterstitial:顯示admob插頁廣告
- jumpApp:為了做應用推薦了,在android端會打開google play或者其他應用商店,如果提供了下載鏈接可以直接下載app到本地,ios端直接打開app store
- share:facebook分享接口
以上接口都是各種百度各種google才得到的答案啊,還要寫java和oc,確實有點辛苦。
•吐槽一下
然后再吐槽一下android版的項目模板,用的是eclipse項目,這沒什么不對,但是,要接第三方庫就不方便了呀,筆者接admob的時候,硬生生地放着Intellij Idea不用,而用eclipse完成開發,因為官方的教程里加入admob庫是用eclipse為例的,idea的沒教,然后只會android基礎的筆者就不會了。官方沒給Gradle編譯的項目模板,還好現在筆者通過查閱古籍資料已經把eclipse項目轉為Idea的項目了,編譯也改為Gradle了,Gradle解決依賴確實很方便,已經投入使用,筆者將在下一篇博文里表述筆者的轉化過程。
•開發經歷和累積-小盆宇們坐正了
真正投入egret游戲開發已經有半年多了,也有了自己一套項目模板了,不是用官方的egret create
來創建項目,而是通過ctrl+c和ctrl+v來創建新項目了,適當的時候egret upgrade
一下模板項目,項目模板里沉淀了一下工具類和一些對egret的擴展:
項目模板 |
Alien庫 |
egret游戲項目的構架可以隨你的開發習慣來定,我個人是非常贊賞egret的gui框架的,Dom將as3版的FlexLite改成了egret版的,配合EgretWing做游戲UI,那真是非常舒服的一件事。
所以,也決定了我的項目會用到gui模塊,所以會先把gui模塊編譯到項目中:把{"name": "gui"}
加入到egretProperties.json
的modules節點中,然后運行命令egret build -e
編譯一次引擎。
因為egret目前為止只提供了簡單的功能,並沒有Scene場景這一說(據說以后會有的),所以需要自己去添加實現,在我的項目模板中已經實現了SceneManager
功能在AlienLib中,支持切換特效,也可以自己寫切換特效,還支持場景資源組依賴,可以動態加載場景需要的資源組。對於本地存儲,egret將html5的localStorage
和native整合了,同一為egret.localStorage
,這樣就解決了本地存儲的適配,筆者則在他的基礎上再次做了一次小封裝,在getItem和setItem的時候對key做了處理,因為html5的localStorage
是和站點host掛鈎的,如果同一個站里放了多個游戲,而都是用score這個key來存儲的,那就亂套了。
個人建議,游戲主體不要涉及gui的邏輯,游戲主體最好繼承自egret.DisplayObjectContainer
,我的習慣是一個class GameStage extends egret.DisplayObjectContainer{}
類,然后所有游戲表現邏輯都在這個GameStage
類中,再加一個GameModel
類來處理數據邏輯,一個GameData
用來存放一些游戲數據,一個GameConfig
用來存放一些普通配置(配置不要用json了,比較死,建議用js來寫動態配置,更加靈活,native打包也不會被修改,因為resource目錄先的文件全是暴露的,不安全)、一些關卡配置或一些語言包配置,一個skins文件夾用來存放EgretWing的皮膚文件,一個Views文件夾存放所有gui的視圖類,包括組件、彈出面板和場景。
筆者的習慣是新建一個ScenePlay
皮膚,在里面添加一個UIAsset
,命名為gameStageContianer
,寫一個名為ScenePlay
的類繼承自SceneBase
,class ScenePlay extends alien.SceneBase {}
,然后重寫他的createChildren():void
方法,將gameStage
實例放到UIAsset
里this.gameStageContainer.source = this._gameStage = new GameStage(this.onGameResult.bind(this));
,最后,通過事件或者callback來完成GameStage和ScenePlay之間的交互。
如果GameStage非要和GUI直接打交道,比如內外特效:在GameStage里的一個星星要飄到Gui的星星槽里,那只能通過坐標傳遞,把GameStage中星星的坐標給ScenePlay,讓ScenePlay播放一遍飄動過程,記得把GameStage里的星星隱藏掉。
•Native Code - js通信
如果你是用webView給游戲打包的,那么通信就用webView的js接口,比較簡單的。
如果你是用Support打包的,那么就要用到Egret提供的接口了。這個接口是歷經重重磨難的,為什么呢?從第一版的一個ExternalInterface類,演變到了現在層層包裝的版本,其實是一樣的。據官方認識透露,做這么多調整是為了迎合一些第三方平台的胃口,這些第三方平台固執己見,堅持不改動自己的接口,所以只能egret來修改了。以上說的是android版的接口,ios版的一直沒變,還是朴實無華的ExternalInterface類。
目前,android版通信接口為直接調用EgretGameEngine的實例提供的方法,有四個:
- public void enableEgretRuntimeInterface(),用來啟動通信接口,是必須的。
- public void setRuntimeInterface(String var1, final Object var2),用來添加接口,其中第一個參數為接口方法名,即js直接調用的方法名,第二個參數是一個Object實例,這個Object實例需要有一個callBack方法,下文會說明。
- public void setRuntimeInterfaceSet(HashMap var1),用途和2差不多,只是為了方便集中添加接口。
- public void callEgretInterface(final String var1, final String var2),調用js方法,第一個參數為接口方法名,第二參數為參數,參數僅支持文本。
對於第二個方法中的Obectj實例,也是經歷了很多變革。起初,這個參數類型並不是Object,而是IExternalInterface接口,是需要實現這個接口的類才行,實現這個接口需要實現一個void call(String args)的方法,這個方法就是js在調用java時唯一調用的方法,參數類型依然是String。后來為了迎合第三方平台,這個接口被去掉了,成了純Object類即可,但是必須要有一個callback方法(b是小寫的),egret內部用了反射來調用這個方法,坑爹的是,這個方法現在又改了,成了callBack(B是大寫的),據透露是egret內部某程序員搞的,至此,這個方法已經沒人改動了,那就這樣吧。
•最后,我來介紹一下IDE,我只能介紹我用過IDE了,選擇很多
- sublime text:挺簡潔的編輯器,很適合代碼編寫,但是我只是拿他來編寫簡單的代碼,大項目涉及到各種變量跟蹤、大綱查詢、集成編譯等
- notepad++:在大學里的時候用過,當時來說是個好東西了,比notepad好至少,還能裝插件,可以直接把代碼通過ftp插件提交到服務器
- Aptana:這個IDE估計很少人用過吧,他就是一個eclipse的插件,適合做web開發,前端和后端皆可,eclipse的編輯模式是我至今都愛不釋手的。他還捆綁了很多實用插件,用起來確實很上手
- Visual Studio:我個人很不喜歡,但做網站的時候也用過,egret開發者可以安裝egret-vs插件,就可以更快捷地開發egret游戲了
- WebStorm:如果說eclipse是高材生,那么webstorm就是很帥的高材生了,同位java開發的IDE,webstorm被jetbrain包裝得如此帥氣,各種爽翻了的插件
- Intellij Idea:和webstorm一樣都是jetbrain家族的ide,那還是在做as3頁游開發時候用的IDE了,我就是從eclipse家族轉到idea家族的,從eclipse轉到idea,改了一些習慣,快捷鍵習慣。
那么我推薦的WebStorm了,他自帶了TypeScript的插件,還可以自定義File Watch,實時編譯Ts為js。還有一個好處就是,他可以添加External Tools,就是添加外部工具,並且綁定了快捷鍵,就可以一鍵實現很多命令組了,比如筆者就“一鍵”實現了egret的編譯:
打開File>Settings>Tools>External Tools
,就可以添加工具了,如圖
添加一個Tools>
•在開發中不斷地提高自己,累積開發經驗,才是學習技術的快樂所在。
淺出完畢,下課,走着!
2016/07/03添加:
只怪筆者當初愚笨,覺得Egret Native的實現方式很精明,其實這中實現方式在筆者現在的項目里開始露出雜毛了,這個種底層抽象程度過高的方式,導致script code比重過高,而native code比重減少,導致運行效率跌落很多,項目做大了,同志們你們就知道了。所以筆者正在開始跳坑,試試跳進其他引擎的坑瞧瞧!
轉載請注明原地址:http://www.cnblogs.com/rockyf/p/analysis-of-egret.html