《割繩子》HTML 5版背后的開發(fā)故事
啟示
在IE9中作為一個HTML5應(yīng)用來運(yùn)行,從原始的iOS源碼改寫而來。Cut the Rope 是一款人見人愛的小游戲。所以我們有了個點(diǎn)子,即通過使用HTML5將這款游戲放到網(wǎng)上以便讓更多的人能接觸到它。
為了做到這一點(diǎn),微軟的IE團(tuán)隊和ZeptoLab團(tuán)隊(游戲的開發(fā)者)以及Pixel Lab的專家們合作以便將Cut the Rope 的網(wǎng)絡(luò)版本實(shí)現(xiàn)。最終效果要能將游戲毫不失真地翻譯成網(wǎng)絡(luò)版本,并且能展示出HTML5的強(qiáng)大功能:畫布提供的繪圖、基于瀏覽器的音頻和視頻、CSS3風(fēng)格以及WOFF字體的個性。
51CTO推薦專題:HTML 5 下一代Web開發(fā)標(biāo)準(zhǔn)詳解
如果你想玩一下Cut the Rope 的HTML5版本,就去下面這個網(wǎng)址吧:www.cuttherope.ie.
我們覺得HTML5版本的游戲讓網(wǎng)絡(luò)更有趣了,同時,它也展示了IE的上一個版本因支持開放標(biāo)準(zhǔn)而顯示出的長處。因此,我們想要分享一些開發(fā) Cut the Rope 過程中的技術(shù)細(xì)節(jié),以便幫助構(gòu)建你自己的HTML5站點(diǎn),并最終為Windows 8 Store做準(zhǔn)備!
從Objective-C到 JavaScript
在將Cut the Rope應(yīng)用到一個新平臺上的時候,我們希望我們保留了這個游戲的獨(dú)特的物理特性、動作以及風(fēng)格。所以,在開始的時候,我們想要改寫iOS版本(而不是重寫)。我們仔細(xì)分析了用Objective-C寫成的原始版本,發(fā)現(xiàn)工程量很大,并且很復(fù)雜。iOS版本包含大約15,000行代碼(不包括庫!)代碼中最復(fù)雜的部分是動作、動畫以及繪圖引擎。它們本身就很復(fù)雜,使事情變得更為復(fù)雜的是這三塊之間耦合度很高,并經(jīng)過了大量優(yōu)化。
這是個令人生畏的工作:要將這些代碼在瀏覽器上實(shí)現(xiàn),而又不喪失原先的獨(dú)特個性以及很高的質(zhì)量。為了完成這個工作,我們賭上了Javascript。
在過去,Javascript一直被人看做是速度很慢的語言。坦白講,這種說法在最初的確是對的。老的Javascript引擎是為處理簡單的“腳本”(scripting)類型的工作設(shè)計的(如它的名字所示)。然而,在現(xiàn)在,Javascript引擎已經(jīng)經(jīng)過大量優(yōu)化了。整合進(jìn)just-in-time等功能以后,Javascript執(zhí)行速度已經(jīng)可以接近底層代碼執(zhí)行速度了。
除此以外,我們知道使用Javascript編程不同于——并且需要的思維方式也不同于——用編譯型語言編程。當(dāng)我們將這個游戲從Objective-C改寫過來的時候,我們知道應(yīng)該充分利用Javascript編程的不同以及優(yōu)點(diǎn)。
一個明顯的例子是在Javascript中缺少structs。Structs是相關(guān)屬性的輕量級的聚合。使用Javascript對象來聚合一系列屬性是很容易的,但是這和使用一個合適的struct是很不同的。第一個不同是一旦structs被賦值給一個變量或則傳遞到一個函數(shù)的時候,它都會被復(fù)制。因此,一個使用如Objective-C這樣的編譯型語言編寫的函數(shù)可以修改以參數(shù)形式傳過來的struct的值,而又不改變原來調(diào)用函數(shù)中的值。即使是在同一個函數(shù)中,將一個不同的值賦給struct也會將值復(fù)制一遍。而Javascript對象,是通過引用傳遞的。所以一個函數(shù)修改了一個對象參數(shù)的時候,原調(diào)用函數(shù)也能看到這個變化。
一個用來模仿structs的簡單的方式是每當(dāng)將Javascript對象作為賦值對象或者參數(shù)傳遞的對象時都創(chuàng)建一個副本對象。在底層語言(native languages)中,使用structs的開銷是很小的。但在Javascript中創(chuàng)建一個對象則會有很大開銷,因此我們要非常小心,減少創(chuàng)建對象的次數(shù)。特別是在賦值的時候,我們盡可能地復(fù)制單個屬性,而不是創(chuàng)建一整個新的對象實(shí)體。
另一個例子是Objective – C代碼庫面向?qū)ο蟮谋举|(zhì)。與傳統(tǒng)的基于對象的繼承不同,JavaScript提供了基于原型屬性(Prototype property)的繼承。這是對基于對象的繼承的一個高度簡化的形式,與傳統(tǒng)的Objective – C這樣面向?qū)ο蟮恼Z言不兼容。幸運(yùn)的是,有各種各樣的類庫,可以幫助你寫的面向?qū)ο缶幊?OOP)風(fēng)格的JavaScript代碼,我們使用的類庫是一個非常簡單的由John Ressig寫的。 (需要注意的是,ECMAScript5,最新版本的JavaScript的規(guī)范,也提供了對一些類的支持,但我們選擇不使用它,因為我們對該版本的語言不熟悉,而我們的開發(fā)進(jìn)度非常緊張)。
除了將代碼從Objective-C改到Javascript,我們還需要將圖像代碼從OpenGL改到HTML5的Canvas API??傮w上說,這一切都進(jìn)行地很順利。Canvas是一個很快的渲染表面,特別是在一個API由硬件加速的瀏覽器中(比如IE9)。
一個使用帆布API完成的aliased lines來畫繩子的例子。令人驚訝地是,我們遇到了好幾個地方,都是Canvas比在移動版本Cut the Rope中使用的OpenGL ES提供了更多功能的。一個例子是畫anti-alias lines。在使用OpenGL畫anti-aliased lines的時候,需要將一條線鑲嵌到一個三角形地帶中,并且將末端的渾濁部分褪色以完成透明化。而在HTML5的canvas中,anti-aliasing lines的繪制是由line API自動完成的。這意味著我們實(shí)際上需要從OpenGL版本中去掉一些代碼。將OpenGL代碼中的三角形頂點(diǎn)數(shù)組解約掉可以提供更好性能。
最終,我們有幾乎15,000行代碼在瀏覽器中執(zhí)行(它已經(jīng)被最小化了,所以如果你在瀏覽器中查看源代碼的時候,你會看到少得多的代碼)??紤]到這么多代碼帶來的復(fù)雜性,Denis Morozov(ZeptoLab開發(fā)部門的總監(jiān),the Director of Development at ZeptoLab)在開始的時候問了一個問題:HTML5能給我們我們所需要的速度和性能嗎?
為了回答這個問題,我們創(chuàng)建了一個早期的“性能”里程碑,在這里,我們集中精力去得到游戲運(yùn)行時難度最高部分的最小版本。也就是說,我們想要看一下繩子看起來是什么樣子的,以及我們是否能在瀏覽器中處理復(fù)雜的物理引擎。
Performance性能
項目開始以后三個星期,我們最終有了物理和繪圖引擎的基本部分,以及一個簡單的用于啟動動畫的計時器?,F(xiàn)在,我們可以在游戲場景中呈現(xiàn)出一些繩索,一顆星星,以及一個Om Nom sprite。不錯的進(jìn)步!第四周的時候,我們加入了一些基本的和鼠標(biāo)的互動,這樣,我們就能真正開始玩游戲了。我們在開發(fā)的過程中一直都在測試性能,并且希望ZeptoLab的團(tuán)隊能夠給我們一些反饋。
當(dāng)我們把這些代碼和ZeptoLab分享的時候,他們對這些代碼在瀏覽器中的性能表現(xiàn)感到驚喜(尤其是游戲的速度和平滑度)。說句實(shí)話,我們一直都提著一口氣呢。我們希望Javascript能快點(diǎn),因為物理計算非常復(fù)雜,并且有實(shí)時性要求。這是一個很好的例子,證明了人們過去認(rèn)為Javascript很慢的觀點(diǎn)實(shí)際上是錯的。最新的Javascript引擎是非??斓摹?/p>
在這個項目中,我們在IE9中預(yù)覽了游戲。當(dāng)你加載了游戲的時候,IE9的Chakra JavaScript引擎在一個后臺線程中將代碼進(jìn)行了預(yù)編譯——就像一個編譯器編譯Objective-C 或者 C++一樣。然后,它實(shí)時將編譯過的代碼(字節(jié)碼)發(fā)送給游戲線程去執(zhí)行。執(zhí)行速度幾乎和本地執(zhí)行速度一樣。令人驚訝的是,這樣的性能是來自于Javascript引擎,我們不需要在代碼中做任何特殊處理。

項目早期幀率檢測結(jié)果(注意幀率上限是60FPS)我們在Javascript上打的賭成功了,因此,我們將注意力轉(zhuǎn)向了硬件和瀏覽器。由于IE的硬件加速堆棧以及我們在 Disney Tron和其他一些HTML5站點(diǎn)上積累的經(jīng)驗,我們對于游戲在測試機(jī)器上的完美表現(xiàn)毫不擔(dān)心。我們很輕易地達(dá)到了上限60 FPS(幀/每秒)。但是,我們想要確認(rèn)游戲在其他硬件和其他瀏覽器上也能表現(xiàn)得很好。下面是我們經(jīng)過一些初步測試后所看到的結(jié)果。
根據(jù)測試數(shù)據(jù),我們將30 FPS(幀/每秒)設(shè)置為最小閾值。當(dāng)瀏覽器速度低于這個閾值的時候,我們將會通知用戶。他們?nèi)匀豢梢酝孢@個游戲,但是我們會通知他們在游戲中他們可能會感覺到一些遲緩現(xiàn)象。這確保了這個游戲能支持不同硬件和軟件,并且提供給玩家我們所能提供的最好體驗。
我們想要指出兩件事情。第一件事,這個游戲的現(xiàn)有版本在桌面PC機(jī)和Mac機(jī)上使用鼠標(biāo)玩時效果是最好的。我們還沒有加入對觸屏輸入的只支持,但在未來的版本中,我們會考慮這一點(diǎn)。
第二件事,現(xiàn)有的Chrome版本(version 16)有一些已經(jīng)為大家所知的和媒體播放相關(guān)的問題,使得Cut the Rope中的聲音飄忽不定。我們進(jìn)行了深入調(diào)研,試圖用不同格式(包括WebM)重新編碼媒體文件,但是沒有找到一個合適的格式或者M(jìn)IME配置或者其他任何方案來有效解決這個問題。這個問題看起來是瀏覽器的bugs以及已經(jīng)為大家所知的問題。更重要的是,盡管聲音時斷時續(xù),游戲玩起來還是非常有意思的??紤]到這一點(diǎn),我們一方面可以說IE9的用戶能免費(fèi)得到一個很棒的應(yīng)用,另一方面,Chrome以及一些Firefox用戶可能會遇到一些聲音上的問題,但他們會注意到我們退回使用了一個flash插件來確保聲效和音樂都能正常工作。
工具
關(guān)于HTML5的一件很好的事情是你不需要學(xué)習(xí)一門新的語言來利用這項新技術(shù)的強(qiáng)大功能。如果你知道并且懂得Javascript,那么你就能實(shí)現(xiàn)一個現(xiàn)代瀏覽器所能實(shí)現(xiàn)的所有功能。你甚至可以創(chuàng)建一個像這個游戲一樣的你自己的游戲!
代碼編輯器以及開發(fā)環(huán)境

Visual Web Developer 2010 Express可以免費(fèi)下載使用,是一款很棒的編輯器,即使是對有經(jīng)驗的Web開發(fā)者來說也是如此。

分析器截圖,圖中內(nèi)容是對Calc2PointBezier函數(shù)中花費(fèi)的不合比例的時間(Calc2PointBezier函數(shù)是用來計算繩子每節(jié)的位置)。
有一些很好的免費(fèi)工具,可以讓我們更容易地使用Javascript和HTML5。我們的大多數(shù)開發(fā)工作都是在Visual Web Developer 2010(“快捷”版本可以在這里免費(fèi)獲得)中完成的。這是一個非常健壯的Web編輯器,帶有Javascript以及CSS自動完成功能。更好的一點(diǎn)是:它是免費(fèi)的!我們在Windows7的IE9上完成了我們的大多數(shù)測試,并且我們也時不時在Firefox、Chrome、Safari以及IE10的開發(fā)者嘗鮮版??傮w上說,主流瀏覽器對于我們所使用的HTML5的特性都有比較一致的實(shí)現(xiàn)。在大多數(shù)情況下,我們在IE9上測試通過的特性在其他地方也運(yùn)行得一樣好。
清查我們的資源加載器(Resource Loader)!
Cut the Rope有一個非常獨(dú)特的細(xì)節(jié)化的視覺風(fēng)格——有很多圖片、音頻和視頻,并且花費(fèi)也很小。最終達(dá)到的效果就是這個游戲比一般的網(wǎng)站要大很多。綜合起來說,它大概有6MB(而一般的網(wǎng)站是200-300K)。這些多媒體資源要花費(fèi)一段時間才能下載,而如果資源沒有下載到位,我們看不到網(wǎng)頁上的內(nèi)容,我們是無法開始游戲的。在一個典型的網(wǎng)頁中,如果你缺掉了一兩幅圖,它仍然是可以運(yùn)行的,但在HTML5的API(drawImage)中,如果圖像無法獲取的話,這一API就會崩潰。
為了解決這個問題,我們想要創(chuàng)建一個資源加載器,用來下載頁面所需要的所有內(nèi)容,并且當(dāng)下載完成后,給我們一個好的反饋。這一點(diǎn)小代碼能做很多很棒的事情:
1.它屏蔽了不同瀏覽器之間對下載處理的不同以及它們告知你進(jìn)度的方式的不同。
2. 它能讓你決定事物下載的順序(你可能會想要先下載大文件,或者你想要在下載游戲圖形之前先下載所有菜單圖像)。
3.最終,它可以智能提醒你事物的到達(dá),這樣就可以通知用戶進(jìn)度情況,甚至可以開始部分游戲。
創(chuàng)建這些類型的庫是很難做好的。由于我們對于這些庫的效果感到十分滿意,因此我們想要分享我們的資源加載器的代碼給你。最終的成果形式是PxLoader,一個Javascript的資源加載器庫,你可以使用它為HTML5應(yīng)用、游戲、站點(diǎn)制作預(yù)加載器。它是開源免費(fèi)的。你可以從頁面頂端抓取它,或者點(diǎn)擊這里。
IE中的性能工具
另外一個在開發(fā)過程中不可或缺的工具是IE9中的Javascript分析器(JavaScript Profiler)。分析器能讓你發(fā)現(xiàn)你的代碼中的熱點(diǎn)以及瓶頸。在我們第一次做性能評估的時候,我們發(fā)現(xiàn)在一些機(jī)器上我們一直困在了20或者30幀/每秒,這使得我們幾乎要放棄了。
我們做了一些最初的代碼檢查,但是什么都沒有檢查出來。我們使用分析器加載了游戲,發(fā)現(xiàn)我們在satisfyConstraints()函數(shù)上花了太多時間。這個函數(shù)是用來計算有關(guān)繩子的一些物理性質(zhì)的數(shù)字。我們用來改寫的Objective-C版的實(shí)現(xiàn)是用遞歸實(shí)現(xiàn)的,遞歸每加深一層,就會傳遞一個新的對象。
通過Microsoft的一些指導(dǎo),我們決定將遞歸函數(shù)替換成一個“解開”的循環(huán)版本。結(jié)果是驚人的。我們在每一個瀏覽器中都看到了10倍以上的性能提升。坦白說,如果沒有IE9的分析器工具,我們永遠(yuǎn)都不可能發(fā)現(xiàn)這一點(diǎn)。
下一步是什么?
九月,Microsoft展示了一個Windows8的開發(fā)者嘗鮮版。在這一聲明以后,HTML5將會更有趣,因為Metro風(fēng)格的應(yīng)用可以用好幾種開發(fā)工具集開發(fā),包括HTML5。這意味著Web開發(fā)者可以將為Web所寫的代碼拿來很容易地?zé)o縫移植到Windows8中。為在線應(yīng)用的投資將來可以在Windows Store中得到實(shí)實(shí)在在的回報。
事實(shí)上,只要再做一點(diǎn)點(diǎn)工作,我們就能將HTML5應(yīng)用移植到Windows8的Metro風(fēng)格應(yīng)用中。可以在這篇博文中讀到關(guān)于 Cut the Rope以及它整合到Windows Store中的內(nèi)容。
我們非常開心看到開發(fā)者使用HTML5構(gòu)建的應(yīng)用。你可以下載IE9并且可以在www.beautyoftheweb.com找到一些其他的很漂亮的站點(diǎn),或者在dev.windows.com下載開發(fā)者嘗鮮版的Windows 8。
要保持關(guān)注,因為這只是一個開始……還會有更多驚喜的!
原文:http://www.webapptrend.com/2012/01/1477.html
【編輯推薦】