egret隨筆-egret淺入淺出


•不知道有多人跟筆者一樣,喜歡學各種技術,但是都不精,但也有一兩項算是精的。

  
  從踏上了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加速渲染。

runtimeindex

•最后一個如果

  博文開頭說了那么多如果,當然,最后一個如果才是關鍵,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的類繼承自SceneBaseclass ScenePlay extends alien.SceneBase {},然后重寫他的createChildren():void方法,將gameStage實例放到UIAssetthis.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的實例提供的方法,有四個:

  1. public void enableEgretRuntimeInterface(),用來啟動通信接口,是必須的。
  2. public void setRuntimeInterface(String var1, final Object var2),用來添加接口,其中第一個參數為接口方法名,即js直接調用的方法名,第二個參數是一個Object實例,這個Object實例需要有一個callBack方法,下文會說明。
  3. public void setRuntimeInterfaceSet(HashMap var1),用途和2差不多,只是為了方便集中添加接口。
  4. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM