成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HTML5游戲引擎深度測評

移動開發(fā)
針對技術(shù)類產(chǎn)品對比,通常有多個維度進行對比,不僅僅是技術(shù)層面,還有許多非技術(shù)層面的內(nèi)容會影響我們的使用結(jié)果。本文從如下幾個維度進行多重對比。

最近看到網(wǎng)上一篇文章,標(biāo)題叫做《2016年 最火的 15 款 HTML5 游戲引擎》。目前針對HTML5游戲的解決方案已經(jīng)非常多,但誰好誰差卻沒有對比性資料。特意花了幾天時間,針對文章中出現(xiàn)的12款免費開源引擎做了一次相對完整的對比分析,希望能對大家有所幫助。

針對技術(shù)類產(chǎn)品對比,通常有多個維度進行對比,不僅僅是技術(shù)層面,還有許多非技術(shù)層面的內(nèi)容會影響我們的使用結(jié)果。本文從如下幾個維度進行多重對比。

  1. 2D與3D
  2. 編程語言
  3. 設(shè)計理念&功能
  4. 工作流
  5. 性能
  6. 學(xué)習(xí)資料
  7. 商業(yè)應(yīng)用

2D與3D、編程語言對比

2D與3D

游戲領(lǐng)域中,最直白的一種分類方法便是2D與3D的區(qū)分。通常我們都會認(rèn)為它們是游戲引擎領(lǐng)域兩類不同的產(chǎn)品。原文中提及的引擎確實是當(dāng)下最為流行的HTML5游戲引擎。很多引擎屬于2D、3D通吃類型,我們通過一個表格進行對比。

編程語言

基于HTML5技術(shù)的游戲引擎,所需要的腳本必定是JavaScript,只有JavaScript腳本語言才能運行于瀏覽器中。但目前市場上,出現(xiàn)了很多JavaScript代替品,例如TypeScript、CoffeeScript、LiveScript等等。不同語言直接的定位不同,語言哲學(xué)也不盡相同。一些游戲引擎在語言選擇上也頗有意思。

Engine 2D Render 3D Render JavaScript TypeScript
Three.js NO YES YES NO
Phaser YES NO YES YES
Pixi.js YES NO YES YES
Egret YES YES YES YES
enchant.js YES NO YES NO
craftyJS YES NO YES NO
Turbulenz YES YES YES YES
cocos2d-js YES NO YES NO
PlayCanvas NO YES YES NO
melonJS YES NO YES NO
Quintus YES NO YES NO
Hilo YES NO YES NO

結(jié)論

可以從表格中看出,下面三個引擎屬于2D和3D通吃類型。

  • Egret
  • Turbulenz
  • PlayCanvas

在Web游戲領(lǐng)域勝出的編程語言是JavaScript和TypeScript。但絕大部分HTML5游戲引擎還是采用JavaScript語言。只有4款引擎選擇支持TypeScript。

從當(dāng)前前端技術(shù)圈環(huán)境分析,未來可能很多前端框架或者引擎會推出響應(yīng)的TypeScript語言分支,從AngularJS宣布將使用TypeScript開發(fā)開始,TypeScript在很大程度上被前端認(rèn)可。不得不說微軟在開源圈這一仗打得漂亮。

設(shè)計理念&功能

架構(gòu)設(shè)計是一門大學(xué)問,對于開源引擎架構(gòu)的設(shè)計模式主要取決于作者的程序哲學(xué)觀點和產(chǎn)品定位。將設(shè)計思路和功能放在一起對比討論,比單獨功能討論更有參考意義。一個引擎的功能并非越多越好,功能應(yīng)圍繞引擎定位而定,這樣的思路在一些引擎中體現(xiàn)尤為明顯,下面我們針對每個引擎一一分析。

Three.js

定位

Three.js項目創(chuàng)建時間是在2010年的4月24日,到目前位置,應(yīng)該算是比較老牌的開源項目了。事實上Three.js定義并非一個游戲引擎。在Github主頁中,作者很明確的定義了Three.js的定位,叫做“JavaScript 3D library”。它僅僅是一個基于JavaScript語言的3D庫而已。當(dāng)然,你可以用它來做任何事情,無論是游戲,還是炫酷的3D展示。

設(shè)計理念

Three.js在設(shè)計之處希望創(chuàng)建一個非常輕量級的3D庫,能夠幫助開發(fā)者快速搭建基于HTML5的3D內(nèi)容。同時,通過暴露簡單的API,將3D內(nèi)容的開發(fā)復(fù)雜性降至最低。

渲染環(huán)境上,Three.js支持WebGL和CCS3D兩種渲染模式。從當(dāng)前使用量和標(biāo)準(zhǔn)普及程度來做分析看,開發(fā)者更加傾向于WebGL渲染方式。

功能

文本主要想對2D游戲引擎做深入分析,所有沒有對Three.js的功能與那些流行的3D引擎加以對比。

Pixi.js

定位

很多人第一眼看到Pixi.js官網(wǎng),都會不自覺的認(rèn)為這是一款游戲引擎。但在主頁中作者對于Pixi.js的定義為“2D WebGL renderer with canvas fallback”,翻譯為中文是一款依賴于canvas的WebGL渲染器。所以當(dāng)你看到Pixi.js提供了為數(shù)不多的功能時,請不要驚訝,因為它只是一款渲染器。

設(shè)計理念

Pixi.js的設(shè)計理念很多程度來源于它的定位,只做渲染器,要把渲染功能做到最強。而這樣的定位,則會讓Pixi.js成為其他引擎的渲染內(nèi)核。你經(jīng)常能看到一些游戲引擎,或者產(chǎn)品都基于Pixi.js而開發(fā)。

最求極致的渲染性能是Pixi.js的首要任務(wù),為了讓Pixi.js更加易于使用,作者在API設(shè)計上更加參考非常成熟的2D渲染架構(gòu) —— Flash,并且提供的API也盡量參考了ActionScript。

例如創(chuàng)建一個顯示對象,在Pixi.js中被封裝為 PIXI.Sprite。如果需要顯示圖像,借助 PIXI.PIXI.Texture紋理進行渲染數(shù)據(jù)填充。最終設(shè)置顯示對象的坐標(biāo),代碼看起來就像下面這樣。

 

  1. var stage = new PIXI.Container(); var texture = PIXI.Texture.fromImage('bunny.jpg'); var bunny = new PIXI.Sprite(texture); bunny.position.x = 80; bunny.position.y = 60; stage.addChild(bunny); 

Pixi.js中的顯示架構(gòu)完全參考Flash設(shè)計,所有顯示對象組合為一個樹狀數(shù)據(jù)結(jié)構(gòu),但內(nèi)部已針對WebGL渲染方式進行過優(yōu)化,上層使用起來和Flash并無太大差別。

功能

游戲引擎中的功能,我們可以細分非常多分類,一篇文章無法講解所有分類細節(jié)講解明白。我將所有功能做了一個二級分類,方便分析。

Phaser

定位

刻意將Pixi.js放在前面分析,因為Phaser本身并沒有自己的渲染核心。就像Pixi.js的定位不一樣,Phaser的定位是 "Desktop and Mobile HTML5 game framework",中為稱之為“桌面與移動端的HTML5游戲框架”。Phaser并不把自己定義為Engine,而是框架。所以,當(dāng)你看到Phaser的功能設(shè)計和它的渲染內(nèi)核時就不會經(jīng)驗了。

設(shè)計理念

因為將自己定位為游戲框架,所以Phaser在游戲功能方面顯得相當(dāng)全面,你能想得到的絕大部分功能Phaser已經(jīng)替你實現(xiàn)了。在渲染方面,Phaser并沒有自己的渲染內(nèi)核,而是直接引用了Pixi.js。這確實是個明智之舉,因為Pixi.js在渲染性能方面非常強悍。前面已經(jīng)提及編程語言,游戲開發(fā)本身邏輯復(fù)雜,算法較多,Phaser提供對TypeScript的支持也是非常明知的。

架構(gòu)方面,Phaser進行非常多的高度封裝。就顯示部分而言,如果你使用過Pixi.js就是發(fā)現(xiàn),設(shè)計思路本身差別不大,但API使用起來則方便很多。Phaser為一準(zhǔn)備好了游戲所需要的一切。當(dāng)我們像創(chuàng)建一個游戲界面時,可以在Phaser初始化時針對不同階段進行定制。

 

  1. var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); 

正向上面這行代碼,Phaser為我們定義了 preload 、 create 、 update 等方法,使用時只需要填寫callback函數(shù)即可。在資源加載時,Phaser會為你調(diào)用 preload 回調(diào)。 當(dāng)畫面刷新時,可以調(diào)用 update 回調(diào)。

其他方面,信號和插件系統(tǒng)算是Phaser的最大特色了。

功能

Phaser功能眾多,但絕大部分應(yīng)用其他第三方作為實現(xiàn)。

Egret

定位

Egret算是HTML5游戲引擎中的新起之秀,其定位已不單純?yōu)镠TML5游戲引擎。官方將其定位為“游戲解決方案”,同時也并未過多提及HTML5。究其原因在于Egret不僅僅提供了一個基于HTML5技術(shù)的游戲引擎,更是提供了原生打包工具和眾多周邊產(chǎn)品,使其成為“解決方案”。

設(shè)計理念

這里單獨分析Egret Engine這個產(chǎn)品,其語言使用TypeScript,有2D和3D版本。在架構(gòu)設(shè)計上,同Pixi.js一樣,參考了Flash成熟的2D架構(gòu)體系。API方面,也參考了ActionScript。不僅如此,由于TypeScript的緣故,在事件系統(tǒng)中,也仿照ActionScript實現(xiàn)了 addEventListener 這樣的事件注冊機制。

內(nèi)核方面,Egret Engine采用了模塊化的設(shè)計。這樣可以將不同的功能進行解耦。更加有趣的是,F(xiàn)lash中引以為傲的自動臟矩形技術(shù)在Egret Engine中也被實現(xiàn)。在canvas模式下,臟矩形會是渲染性能得到提升,比其他引擎更加有優(yōu)勢。

如果你會Flash,那么Egret Engine對你來說不需要過多的學(xué)習(xí)即可上手。

功能

Egret Engine由于模塊化設(shè)計的原因,將不同功能放到了不同模塊中。這些模塊以庫的形式提供,下面表中是所有支持模塊的總和,但不含平臺API部分,例如微信API的封裝。

enchant.js

定位

enchant.js并非一個引擎,而是一個框架。同時,enchant.js也不僅僅用于游戲,還可以用于app。

設(shè)計理念

鑒于支持游戲開發(fā)和APP開發(fā),這個框架必定會顧全一些東西,不能在游戲方面放開手腳。架構(gòu)設(shè)計上,沒講所有的元素全部按照OOP方式設(shè)計,內(nèi)部使用實踐驅(qū)動,并有效的結(jié)合了異步處理。游戲方面則僅僅對動畫相關(guān)功能做了支持。enchant.js框架提供了一套插件機制,你可以將使用到的功能模塊作為插件注入到enchant.js框架中。

enchant.js還特意提供了一個在線的圖像庫,方便開發(fā)者免費使用其中的素材。當(dāng)從游戲效果來看,以小游戲居多。

功能

enchant.js框架自身提供的功能非常有限,如果需要其他功能,必須自己擴展或者尋找響應(yīng)的插件。

craftyJS

定位

craftyJS將自己定義為針對JavaScript游戲的框架。

設(shè)計理念

由于框架的定位,craftyJS在設(shè)計上提供了一些系統(tǒng)級別支持,例如將canvas和Dom兩種渲染方式封裝為同一套API,盡量小的文件體積,實體組件系統(tǒng),顯示對象封裝,碰撞檢測,事件系統(tǒng),還有很多功能組件模塊。所有的模塊都依賴于實體組件系統(tǒng)的設(shè)計。

在實際測試中,craftyJS在API上的設(shè)計思路也是使用起來最為不舒服的一個。

功能

Turbulenz

定位

Turbulenz引擎實際上是為自己的游戲渠道中的游戲提供的游戲引擎。因為和自身渠道綁定,所以在引擎中提供了很多l(xiāng)ow level API。借助這些底層API,可以呼叫Turbulenz游戲渠道中的一些系統(tǒng)級別功能。

設(shè)計理念

由于Turbulenz引擎更多的為自己設(shè)計,更多的提供runtime支持,從嚴(yán)格意義上將,Turbulenz引擎不算是純正的HTML5游戲引擎。為了滿足其自身渠道的需求,Turbulenz引擎力求增加更加完整的功能,同時提高其運行性能。

功能

由于Turbulenz對很多功能做了擴展,同時推出Low Level API和 High Level API。這里不再對其中龐雜的系統(tǒng)進行功能分析,大家如果有興趣可以到其官網(wǎng)查看。

cocos2d-js

定位

cocos2d-js是喊著Cocos2D-X的金鑰匙出身的,它僅僅是Cocos2D-X的一個HTML5實現(xiàn)的分支。

設(shè)計理念

cocos2d-js和Cocos2D-X的設(shè)計理念相同,你能夠看到所有的API以及語法都完全參考Cocos2D-X。國內(nèi)對于Cocos2D-X已經(jīng)非常了解,這里就不做過多介紹。

功能

cocos2d-js的功能提供的相當(dāng)完整,你在游戲中需要的功能幾乎都能夠找到。

PlayCanvas

定位

PlayCanvas主要用于3D渲染,本文還是以2D討論為主,對PlayCanvas的分析就不做過多分析。

melonJS

定位

melonJS是一個輕量級的HTML5游戲框架,并且通過插件機制擴展其功能。

設(shè)計理念

melonJS在所有的功能設(shè)計上都是輕量級的,你可以看到很多功能,并且在此基礎(chǔ)之上搭建你自己所需要的功能模塊。melonJS對于Tiled Map支持非常好,在兼容性方面也是melonJS關(guān)注的重點。

功能

Quintus

定位

Quintus將自己定位為簡單好用的JavaScript游戲引擎,同時支持移動和PC端。

設(shè)計理念

Quintus設(shè)計為模塊化和輕量化,盡量使用簡潔友好的JavaScript語法。在JavaScript的API結(jié)構(gòu)設(shè)計中,盡量使用標(biāo)準(zhǔn)的OOP模式。Quintus還借助了jQuery,并通過jQuery插件實現(xiàn)事件和一個選擇器的語法。語言設(shè)計層面上Quintus沒有設(shè)計限制使用傳統(tǒng)的繼承,這使得其中得組件模型更加容易被復(fù)用。

功能

Quintus自身并不支持WebGL,同時提供的功能也較少,在Github中排名也很靠后。

Hilo

定位

Hilo這個引擎來源于阿里前端團隊,從官網(wǎng)的主頁上看,這個引擎的定位比較模糊。Hilo作為一個跨終端的互動小游戲解決方案,同時有稱綜合解決方案。從它的演變來看,Hilo屬于阿里前端在實踐總總結(jié)出來的一套工具庫。整體引擎并非最初有計劃設(shè)計構(gòu)想。

設(shè)計理念

從Hilo支持的特性上看,Hilo的設(shè)計思路更加偏向與前端開發(fā)者,而非游戲開發(fā)者。Hilo提供了多種模塊范式的包裝版本,實際上在滿足不同前端開發(fā)者習(xí)慣。這些特性完全是前端工程師所偏好的內(nèi)容,對于游戲來講,這些內(nèi)容可能優(yōu)先級并非最高,作為阿里內(nèi)部團隊的常用引擎,對于阿里來說應(yīng)該非常合適,應(yīng)用場景做簡單營銷互動小游戲足以。

功能

Hilo功能相對比較簡單,對于游戲開發(fā)來說,缺失功能較多。

工作流

對團隊開發(fā)來講,工作流搭建是非常重要的,我個人比較看重這點。如果是小型團隊或者個人開發(fā)者可能對此需求并不大。當(dāng)項目規(guī)模變大時,一個好的工作流會事半功倍。

因為引擎的功能不同,所以涉及的工具也會有所差異,這里就不再做表對比了。

Three.js

3D并不在本篇文章的討論范圍之內(nèi),同時Three.js也并非游戲引擎,不存在游戲開發(fā)工作流一說。這里簡單介紹一下Three.js所提供的在線編輯器。

Three.js提供的在線編輯器應(yīng)該是基于Three.js開發(fā)的,功能不多,但相當(dāng)小巧。

Pixi.js

Pixi.js作為一個渲染器,其工具支持也是相當(dāng)清爽,除了一個程序庫之外,沒有提供任何工具。

Phaser

Phaser和Pixi.js一樣,沒有提供任何工具支持,在其官網(wǎng)上只是推薦了兩個代碼編輯器。還提供了一個簡單的在線代碼編輯器。

Egret

Egret提供的工具非常多,也復(fù)合其解決方案的定位。在Egret整個體系下你可以看到如下工具支撐。

Egret Wing:Egret出品的一個IDE編輯器。在提供代碼編輯功能的同時,還內(nèi)置可視化的UI編輯器。與Egret Engine中的GUI、EUI框架配合使用。

ResDepot:這是個小工具,用來配置游戲資源加載表。如果游戲資源多的話,用這個小工具拖拽一下就完成了。

TextureMerger:一個紋理合并的小工具,功能有點像TexturePacker。

DragonBones Pro:針對Egret中骨骼動畫解決方案提供的DragonBones動畫編輯器。

Egret Inspector:一個基于Chrome瀏覽器的插件,可以針對Egret游戲進行調(diào)試。

Egret iOS & Android Support:這兩個東西可以將你的HTML5游戲打包成原生APP。

還有一些其他的工具,但定位與游戲開發(fā)不同,有興趣可以去它的官網(wǎng)看。

從上面的分析看出,Egret在工作流的支持上做的還是非常完成的,從Wing的代碼編寫,到ResDepot和TextureMerger的資源整合,再到Inspector調(diào)試,和原生打包。游戲開發(fā)過程中的每個環(huán)節(jié)基本都有工具支撐。

enchant.js

enchant.js 沒有提供任何工具支撐,在官網(wǎng)中也沒有任何相關(guān)支持工具的介紹。

craftyJS

craftyJS也沒有提供任何工具支撐,僅僅是一個開源代碼庫。

Turbulenz

Turbulenz在你下載的目錄中包含了很多工具,大部分與格式轉(zhuǎn)換相關(guān)。所有工具均為命令含小工具,沒有提供任何可視化操作軟件支持。

cocos2d-js

Cocos2d-js近年來變化很大,但對于JS這個分支的支持卻少之又少。前一段時間新出了一個工具叫做Cocos Creator。我沒有具體使用過,但看截圖仿佛有Unity3D的影子。從介紹中看,應(yīng)該對游戲支持還是不錯的,編輯方面目前還欠缺。

PlayCanvas

PlayCanvas也提供了一個在線編輯器,不過是針對它的3D功能。編輯器看上去和Three.js提供的在線編輯器份很相似。這里直接借用官方文檔中的截圖給大家看一下。

melonJS

melonJS除了源碼庫以外,也沒有提供任何工具支持。但在其官方主頁中,包含幾個其他編輯器的連接。比如著名的Tiled地圖編輯器等。

Quintus

Quintus沒有提供任何工具支撐。

Hilo

Hilo沒有提供任何工具支撐。

總結(jié)

結(jié)果并不出乎意料,對于開源游戲引擎來講,維護庫就是耗費作者很大一部分精力,更何況去制作編輯器之類的軟件產(chǎn)品。很多引擎都會依賴一些比較流行的第三方工具,例如Tiled、TexturePacker等等。雖然可以實現(xiàn)功能,但整個工作流搭配起來還是多多少少會有一些問題。只有Egret和Cocos2D-js提供了相關(guān)可視化編輯工具。而這兩對于工作流的理解則完全不同。從產(chǎn)品中不難看出,Cocos2D-JS更像Unity3D,提供一個大而全的軟件給開發(fā)者用。Egret則是什么角色用什么工具,將產(chǎn)品按照角色劃分,針對不同角色和開發(fā)流程中的各個環(huán)節(jié)進行產(chǎn)品設(shè)計。

相對來說,Egret的這種方式使得每個工具更加垂直,能夠做的功能也更加深入,不會讓工具顯得臃腫。而Cocos Creator則力求完整,一個軟件解決所有事情。

性能

性能測試上,我只針對2D游戲引擎做了一個渲染壓力測試。

測試內(nèi)容為同屏渲染對象數(shù)量相同的情況下進行幀頻數(shù)據(jù)對比,為了保證測試的公平性,我使用同一臺電腦,相同版本的Chrome瀏覽器進行測試,游戲場景尺寸均為800*600,顯示的圖片也為同一張。每個引擎進行同屏5000、10000、20000個顯示對象渲染。

其中craftyjs引擎渲染出現(xiàn)問題,這里不作數(shù)據(jù)對比。
Quintus引擎不支持WebGL渲染模式,因此這里頁不作數(shù)據(jù)對比。
Phaser渲染內(nèi)核使用Pixi.js,因此Phaser渲染數(shù)據(jù)參考Pixi.js結(jié)果。

所有引擎編寫的代碼大致相同,開始做for循環(huán),創(chuàng)建定量顯示對象,然后在循環(huán)中對每個顯示對象做旋轉(zhuǎn)操作。

測試代碼如下:

Pixi.js

 

  1. var renderer = PIXI.autoDetectRenderer(800, 600,{backgroundColor : 0x1099bb}); document.body.appendChild(renderer.view); var stage = new PIXI.Container(); var texture = PIXI.Texture.fromImage('bunny.jpg'); var tnum = 5000; console.log("render Object Number:",tnum); var bunnys = []; for(var i=0;i<tnum;i++) {     var bunny = new PIXI.Sprite(texture);     bunny.position.x = Math.random()*800;     bunny.position.y = Math.random()*600;     stage.addChild(bunny);     bunnys.push(bunny); } animate(); function animate() {     requestAnimationFrame(animate);      for(var i=0;i<tnum;i++)     {        bunnys[i].rotation += 0.1;     }     renderer.render(stage); } 

Egret

 

  1. class Main extends egret.DisplayObjectContainer {     public constructor() {         super();          this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);     }      private tnum:number = 100000;     private bunnys:egret.Bitmap[] = [];      private onAddToStage(event:egret.Event)      {         console.log("render Object Number:",this.tnum);         this.stage.dirtyRegionPolicy = egret.DirtyRegionPolicy.OFF;         RES.getResByUrl('resource/bunny.jpg',this.onComplete,this,RES.ResourceItem.TYPE_IMAGE);     }      private onComplete(event:any)     {         var img:egret.Texture = <egret.Texture>event;         for(var i:number=0;i<this.tnum;i++)         {             var bunny = new egret.Bitmap(img);             bunny.x = Math.random()*800;             bunny.y = Math.random()*600;             this.addChild(bunny);             this.bunnys.push(bunny);         }         this.addEventListener(egret.Event.ENTER_FRAME, this.animate,this);     }      private animate(evt:egret.Event)     {         for(var i:number=0;i<this.tnum;i++)         {             this.bunnys[i].rotation += 1;         }     }  } 

enchant.js

 

  1. enchant(); window.onload = function () {    var game = new Game(800, 600);     game.fps = 60;    game.preload('bunny.jpg');    game.onload = function() {     var tnum = 100000;     console.log("render Object Number:",tnum);     var bunnys = [];       var scene = new Scene();       game.pushScene(scene);       for(var i=0;i<tnum;i++)         {             var sprite = new Sprite(50, 50);             sprite.image = game.assets['bunny.jpg'];             sprite.x = Math.random()*800;             sprite.y = Math.random()*600;             scene.addChild(sprite);             bunnys.push(sprite);         }         game.addEventListener('enterframe', function() {           for(var i=0;i<tnum;i++)             {                bunnys[i].rotation += 1;             }         });    };    game.start(); }; 

Turbulenz

TurbulenzEngine = WebGLTurbulenzEngine.create({     canvas: document.getElementById("canvas") }); var graphicsDevice = TurbulenzEngine.createGraphicsDevice({}); var draw2D = Draw2D.create({     graphicsDevice: graphicsDevice });  var bgColor = [1.0, 1.0, 0.0, 1.0];   var tnum = 50000; console.log("render Object Number:", tnum); var bunnys = []; for (var i = 0; i < tnum; i++) {     var sprite = Draw2DSprite.create({         width: 50,         height: 50,         x: Math.random() * 800,         y: Math.random() * 600,         color: [1.0, 1.0, 1.0, 1.0],         rotation: Math.PI / 4     });      bunnys.push(sprite); }  var texture = graphicsDevice.createTexture({     src: "bunny2.jpg",     mipmaps: true,     onload: function (texture) {         if (texture) {             for (var i = 0; i < tnum; i++) {                 var sprite = bunnys[i];                 sprite.setTexture(texture);                 sprite.setTextureRectangle([0, 0, texture.width, texture.height]);             }          }     } });  var PI2 = Math.PI * 2; var rotateAngle = PI2 / 360; // 1 deg per frame  function update() {      if (graphicsDevice.beginFrame()) {         graphicsDevice.clear(bgColor, 1.0);          draw2D.begin();          for (var i = 0; i < tnum; i++) {             var sprite = bunnys[i];              sprite.rotation += rotateAngle;             sprite.rotation %= PI2; // Wrap rotation at PI * 2              draw2D.drawSprite(sprite);         }          draw2D.end();          graphicsDevice.endFrame();     } }  function render() {     var tnum = 5000;     console.log("render Object Number:", tnum);     for (var i = 0; i < tnum; i++) {         sprite.position.x = Math.random() * 800;         sprite.position.y = Math.random() * 600;     } }

cocos2d-js

 

  1. window.onload = function(){     cc.game.onStart = function(){         //load resources         cc.LoaderScene.preload(["bunny.jpg"], function () {             var tnum = 100000;               console.log("render Object Number:",tnum);               var bunnys = [];             var MyScene = cc.Scene.extend({                  onEnter:function () {                     this._super();                     var batchNode = cc.SpriteBatchNode.create("bunny.jpg");                     this.addChild(batchNode);                     for(var i=0;i<tnum;i++)                     {                       var sprite = cc.Sprite.create("bunny.jpg");                       sprite.setPosition((Math.random()*800), (Math.random()*600));                       batchNode.addChild(sprite);                       bunnys.push(sprite);                     }                     this.scheduleUpdate();                 },                 update:function () {                    for(var i=0;i<tnum;i++)                     {                       bunnys[i].setRotation(bunnys[i].getRotation()+1);                     }                     this.scheduleUpdate();                 }             });             cc.director.runScene(new MyScene());         }, this);     };     cc.game.run("gameCanvas"); }; 

melonJS

 

  1. var PlayScreen = me.ScreenObject.extend( {     onResetEvent: function() {         me.game.world.addChild(new me.ColorLayer("background", "#5E3F66", 0), 0);         for (var i = 0; i < 5000; i++) {             me.game.world.addChild(new Smilie(i), 3);         }     } });  var Smilie = me.Sprite.extend({     init : function (i) {         this._super(             me.Sprite,             "init",             [                 (-15).random(800),                 (-15).random(600),                 {                     image: me.loader.getImage(game.assets[0].name)                     ,width : 50                     ,height : 50                 }             ]         );         this.rotation = 0;         this.alwaysUpdate = true;     },      update : function () {         this.rotation += 3/180*Math.PI;         thisthis.angle = this.rotation ;         return true;     },}  ); 

Hilo

  1. function init(){     var stage = new Hilo.Stage({         renderType:'canvas',         container: gameContainer,         width: 800,         height: 600     });     var sum = 5000;     var bitmaps = [];     var ticker = new Hilo.Ticker();    ticker.addTick(stage);    ticker.start(true);      for(var i = 0; i < sum; i++) {             var bmp = new Hilo.Bitmap({             image: 'images/hero.jpg',             rect: [0, 0, 50, 50],             x: Math.random()*800,             y: Math.random()*600             }).addTo(stage);             bitmaps.push(bmp);     }      function animate() {         requestAnimationFrame(animate);         for(var i = 0; i < sum; i++) {                     bitmaps[i].rotation += 0.1;         }     }     animate(); } 

我的電腦配置如下:

最終測試結(jié)果

Engine 5000 Display 10000 Display 20000 Display
Pixi.js 60fps 60fps 60fps
Egret 60fps 45fps 24fps
enchant.js 7fps 4fps 2fps
Turbulenz 60fps 60fps 60fps
cocos2d-js 60fps 32fps 15fps
melonJS 4fps 崩潰 崩潰
Hilo 12fps 6fps 3fps

結(jié)論

按照上述測試方法,我們可以對引擎性能排名做一個大致排列:

第一名:Pixi.js 和 Turbulenz
第二名:Egret
第三名:Cocos2d-js
第四名:Hilo
第五名:enchant.js
第六名:melonJS

最后放出一張測試時效果圖

學(xué)習(xí)資料

通常情況下,我們都會選擇一個資料較全的產(chǎn)品進行學(xué)習(xí)使用,畢竟使用過程中會遇到各種各樣的問題。現(xiàn)在游戲引擎的文檔,討論組等都已經(jīng)成為了產(chǎn)品標(biāo)配。下面這個表格就對各個引擎的這些“標(biāo)配”做一個對比。

Engine Document API Document examples forum IRC&Other Language
Three.js YES YES YES 第三方 YES EN
Phaser YES YES YES 第三方 YES EN
Pixi.js YES YES YES 第三方 YES EN
Egret YES YES YES YES YES CN
enchant.js YES YES NO NO NO JP EN
craftyJS YES YES NO 第三方 NO EN
Turbulenz YES YES YES 第三方 第三方 EN
cocos2d-js YES YES YES YES YES CN EN
PlayCanvas YES YES YES YES YES EN
melonJS YES YES YES NO YES EN
Quintus YES YES NO YES NO EN
Hilo YES YES YES NO NO CN

結(jié)論

從上面對比表格可以看出,絕大部分引擎在文檔教程方面做的還是比較深入的,但完成程度不同。大部分都為英文文檔,對于國內(nèi)的開發(fā)者來說可能學(xué)習(xí)起來成本略高。其中兩個支持中文的引擎Egret、Hilo均為國人產(chǎn)品,這兩款引擎在文檔方面,Egret做的相當(dāng)優(yōu)秀,開發(fā)者可以從它的edn.egret.com中查閱大量中文資料。

在學(xué)習(xí)難度上,Egret算是最為簡單的,無論從完整度還是中文普及度上。

商業(yè)應(yīng)用

這部分對比是在商業(yè)產(chǎn)品應(yīng)用中的占比情況。一個引擎被商業(yè)產(chǎn)品應(yīng)用廣泛的情況下,足以證明此引擎具備商業(yè)產(chǎn)品使用價值。通俗的講,別人能用這玩意做出游戲,你也能。所以針對這兩方面進行一下粗略的分析。

我對國外的HTML5游戲市場完全不了解,這個市場分析的東西太大,不好做評價。就分析一下國內(nèi)的,簡單看一下到底哪個引擎用的多。

我用了國內(nèi)比較火的HTML5游戲平臺新浪微博作為數(shù)據(jù)采樣基礎(chǔ),一個人實在精力有限,不可能做的完整。由于客戶端對游戲地址進行了加密,無法直接獲取。所以用了一些調(diào)試工具來看游戲網(wǎng)頁的標(biāo)記,以此判斷游戲到底使用什么引擎制作。

最終統(tǒng)計結(jié)果如下:

游戲名稱 引擎 游戲名稱 引擎 游戲名稱 引擎
CEO養(yǎng)成計劃 純HTML5 全民把妹 Egret 鬼吹燈 laya
一夜成名 純HTML5 決斗西游 Egret 邊鋒斗地主 cocos
上吧主公(萌喵闖三國) 純HTML5 呆呆忍者村 cocos 少女戰(zhàn)機 Egret
三國魂 Egret 全民穿越之宮 Egret 蟲蟲大戰(zhàn) createjs
傳世霸業(yè) cocos 召喚師學(xué)院 cocos 我欲封天H5 Egret
傳奇世界 Egret 全民狂戳 Egret 萌戰(zhàn)姬 Egret
全力游戲 Egret 全民魔魔噠 cocos 我們的萌萌 Egret
全員加速中 Egret 戰(zhàn)神 cocos 藥水英雄 cocos
全民宮斗 純HTML5 全民首富 純HTML5 愚公移山 Egret
坦克風(fēng)云 Egret 無限穿越 cocos 覺醒吧MT cocos
大主宰 cocos 星愿城市 cocos 悟空歸來 – 西游神傳 Egret
大俠歸來 Egret 深海保衛(wèi)戰(zhàn) Egret 美人心計 Egret
大大大掌門 Egret 泡泡奧特曼 Egret 德州撲克H5 Egret
天天賺錢 Egret 暴走大亂斗 Egret 經(jīng)典瑪麗h5 Egret
小鳥情人OL 純HTML5 狂掛傳奇 Egret 少年,好功夫 Egret
少女H計劃 Egret 盜墓英雄 Egret 秘密魔法花園 cocos
少女H計劃2 Egret 神傳 Egret

一共找了50款游戲,如上面表格。50款引擎,使用純HTML5開發(fā)的6款,使用Egret開發(fā)的30款,Cocos2d-js的14款,laya的1款,createjs的1款。

統(tǒng)計結(jié)果如下:

不難看出,Egret 和 Cocos2D-js聯(lián)合瓜分了大部分市場。而Egret占比居然過半,達到58%。看來Egret在國內(nèi)HTML5游戲市場還是非常強悍的。

總結(jié)

  1. Three.js:作為老牌的3D庫,它已經(jīng)有眾多案例,在PC多網(wǎng)頁3D中是目前不錯的選擇。
  2. Phaser:文檔教程,和案例方面都很不錯,功能也算的上豐富。非常適合獨立游戲開發(fā)和小團隊使用。
  3. Pixi.js:作為渲染器,其渲染性能絕對是非常優(yōu)秀的,游戲功能方面支持很差,適合極客程序員把玩。
  4. Egret:性能不錯,在工作流方面支持非常優(yōu)秀,適應(yīng)中度和重度HTML5游戲開發(fā),有較多商業(yè)項目驗證,非常適合商業(yè)團隊使用。
  5. enchant.js:性能偏差,不太推薦。
  6. craftyJS:文檔教程等方面不太完善,很難找到對應(yīng)技術(shù)支持,不推薦。
  7. Turbulenz:性能極佳,但捆綁其自身業(yè)務(wù),不太適合國內(nèi)市場。
  8. cocos2d-js:老牌引擎,其性能在排名中居中,工作流支持相對完整,推薦。
  9. PlayCanvas:重度3D游戲開發(fā)引擎,本文不對3D做推薦。
  10. melonJS:性能不理想,不推薦。
  11. Quintus:不支持WebGL模式,性能較差,不推薦。
  12. Hilo:阿里前端團隊作品,偏向于前端開發(fā)工程師,與游戲?qū)I(yè)開發(fā)距離較大,推薦做HTML5營銷小交互的使用。

 

責(zé)任編輯:李英杰 來源: 簡書
相關(guān)推薦

2015-07-08 16:38:10

Cocos游戲引擎

2013-03-06 15:05:44

移動瀏覽器移動游戲HTML5

2015-07-24 17:08:24

2014-12-30 17:13:51

HTML5

2013-10-21 15:24:49

html5游戲

2014-04-17 09:54:47

HTML5JavaScript

2015-07-10 10:27:21

Cocos游戲開發(fā)引擎

2012-03-06 10:56:32

HTML 5

2013-06-24 14:55:30

HTML5

2015-06-26 11:51:26

HTML5JavaScript

2011-12-09 20:25:16

HTML5

2013-03-06 16:14:16

UCHTML5游戲引擎

2012-05-25 12:50:46

HTML5AppCan

2015-02-28 09:31:25

HTML5JavaScript

2016-04-18 16:58:17

游戲H5市場

2014-11-12 16:00:12

火舞游戲

2015-10-23 13:44:14

巴巴獵

2014-09-24 15:50:05

騰訊X5Egret Runti

2012-04-01 10:02:00

HTML5

2013-01-08 11:00:20

IBMdW
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 爱草在线 | 久久婷婷国产麻豆91 | 成人免费毛片片v | 国产一区不卡在线观看 | 夜夜爽99久久国产综合精品女不卡 | 欧美a区 | 国产福利视频导航 | 久久一区 | 久久精品一区二区三区四区 | 中文字幕免费 | 成人精品视频在线观看 | 国产精品三级 | 欧美中文在线 | 久久久久久久一区 | 日韩av一区二区在线 | 国产精品久久久久久一区二区三区 | 日韩国产欧美视频 | 成人在线观看免费 | 中文av在线播放 | 精品国产乱码久久久久久图片 | 中文字幕第7页 | 国产精品久久久 | 国产色网 | 香蕉国产在线视频 | 久草在线 | 久久精品国产一区二区电影 | 日韩久久久久 | 永久av| 久草免费电影 | 午夜精品一区二区三区在线观看 | 51ⅴ精品国产91久久久久久 | 国产精品国产成人国产三级 | 中文在线一区二区 | 亚洲高清中文字幕 | 国产精品揄拍一区二区 | 欧美在线国产精品 | 色综合99| 亚洲精选一区二区 | 免费观看一区二区三区毛片 | a视频在线观看 | 欧美一区2区三区3区公司 |