前言
迪士尼《Find Your Way to OZ》這個貼近地氣的遊戲我在最新一期《程式設計師》雜誌的《從HTML5555》行動應用現況談發展趨勢》這篇文章裡有所提及,它藉用了近期上映的《魔境仙蹤》電影的設定(設定來自於經典故事《綠野仙蹤》,看過這部電影的同學們會深有感觸),建構了一個等同的宏大遊戲世界。同時迪士尼又和Google合作,把它當作Chrome瀏覽器效能和HTML5技術的一個show case。對於這樣一個使用了WebGL 3D、相機、3D音效等多種先進技術、支援桌面和行動裝置、品質出色的HTML5遊戲,了解它背後的實現原理和技巧必然對我們來說有著非常巨大的參考意義。
這篇文章我早就想翻譯出來,幫助大家更好的了解HTML5在遊戲開發裡的應用和國外的應用情況,但是這篇文章實在太長,所以只能分次刊載,以颯讀者。
此教學在我近期HTML5介紹的文章中難度可稱高級,適合有一定經驗的開發者閱讀和學習。
#介紹
「尋找奧茲之路」是迪士尼為GoogleChrome帶來的全新體驗。它讓你在互動的旅程中穿越堪薩斯馬戲團,然後通過一個巨大的風暴到達奧茲王國。
我們的目標是結合瀏覽器的技術能力,以創造充滿樂趣、身臨其境的體驗,使用者可以與電影之間形成一個強大的聯繫。
這個遊戲的工作實在是太龐大,所以我們只能列出一些章節,把我們認為有趣的技術故事寫出來。教程的難度隨著進度會逐漸增加。
我們有許多人努力創造更好的體驗,但太多無法一一列舉。請造訪該網站,體驗整個頁面下的完整故事。
預覽
在PC端《尋找奧茲之路》是一個豐富的身臨其境的世界。我們把3D和傳統的電影製作靈感結合起來,創造出一個好幾層的接近現實的場景效果。其中最突出的技術是用Three.js引入WebGL,使用CSS3特性來客製化著色器和DOM動畫元素。除此之外,getUserMedia API(WebRTC)增強了互動體驗,讓使用者直接從相機中添加自己的形象,以及WebAudio帶來了3D音效。
但這種科技體驗的神奇之處在於它們是如何融合為一體的。這也是面臨的主要挑戰之一:如何把視覺效果和互動元素融合在一起來創造一個一致的場景?這種視覺的複雜性非常難以管理:很難說清楚我們在任何時間需要發展什麼場景。
為了解決視覺效果和最佳化這個問題,我們大量使用了一個控制面板,用於捕捉我們正在檢查的那個時間點的所有相關設定。在瀏覽器中可以即時修正場景中的一切,例如亮度,縱向深度,伽瑪線等等。任何人都可以在體驗中嘗試調整重要參數的值,參與並發現什麼效果最好。
在分享我們的秘密之前,我要提醒你,它可能會導致崩潰。確保你沒有正在瀏覽什麼重要的東西,並且在訪問該網站的網址時添加?debug=on。等待網站加載,一旦你進入後按Ctrl+I鍵,會看到右手邊出現一個下拉式選單。如果取消選取「退出相機路徑」選項,你可以使用A、W、S、D鍵和滑鼠在空間中自由的移動。
我們不會詳述這裡的所有設置,但是我們鼓勵你試驗:按鍵顯示不同的場景中不同的設置。在最後的風暴場景中有一組額外的按鍵:Ctrl+A,可以切換播放的動畫。在這個場景中,如果你按Esc(退出滑鼠鎖定功能),再次按下Ctrl+I鍵可以進入風暴場景的特殊設定。看看四周,並且截取一些像下面這樣的漂亮明信片。
要做到這一點以確保其對我們的需求具有足夠的靈活性,我們採用了一個很棒的名為dat.gui的框架(可以在這裡看看過去關於如何使用它的教程)。它允許我們能夠迅速改變暴露給遊客的設定。
#有點像繪景
許多經典的迪士尼電影和動畫創作場景意味著合併不同的層。有外景層、單元動畫層,以及實體設置層和透過玻璃繪畫獲得的頂層:這種技術稱為繪景。
在許多方面我們創造的體驗的結構是相似的,即使有些「層」遠遠超過了靜態的視覺效果。事實上,它們根據更複雜的計算影響事物看起來的方式。然而,至少在大畫面的水平,我們處理視圖,將一個合成到另一個之上合。在頂部,你看到一個UI層,其下方是3D場景:它由不同的場景元件組成。
頂部介面層使用DOM和CSS 3建立。事件通訊使用Backbone路由器+ onHashChange HTML5事件來控制哪個區域回應動畫。 (專案原始碼:/develop/coffee/router/Router.coffee)。
教學:Sprite表與視網膜支援
我們依賴有趣的最佳化技術,將多個介面層影像合併為一張單獨的PNG來減少伺服器請求。在這個專案中,介面由多於70 張的圖像組成(不包括3D紋理),並且全部預先載入以減少網站延遲。你可以在這裡看到最新的Sprite表:
正常顯示
Retina顯示屏
以下是我們如何發揮Sprite表優勢的一些技巧,在視網膜裝置上如何使用它們,以及如何將介面盡可能設定的簡潔而整齊。
建立Sprite表
我們使用TexturePacker建立任何你需要的Sprite表格式。在這種情況下,我們採用EaselJS,它非常整潔,並且可以用於創建動畫Sprite。
使用產生的Sprite表
# 一旦建立了Sprite表,你應該看到這樣的一個JSON檔:
<br>
<br>
<br>
<br>
##################### #
{ "images": ["interface_2x.png"], "frames": [ [2, 1837, 88, 130], [2, 2, 1472, 112], [1008, 774, 70, 68], [562, 1960, 86, 86], [473, 1960, 86, 86] ], "animations": { "allow_web":[0], "bottomheader":[1], "button_close":[2], "button_facebook":[3], "button_google":[4] }, }### 其中:##################### images指向sprite表的位址############ images 指向sprite表的位址########### UI元素的座標###[x, y, width, height]################ animations 是每項內容的名稱#################### ######### 請注意,我們已經使用了高清影像來建立Sprite表,然後我們只需透過調整影像尺寸為一半來創建正常版本。 ###### ###整合一切######### 現在,我們只需要一段Javascript程式碼來使用它。 ###
<br>
var SSAsset = function (asset, p) { var css, x, y, w, h; // pide the coordinates by 2 as retina devices have 2x density x = Math.round(asset.x / 2); y = Math.round(asset.y / 2); w = Math.round(asset.width / 2); h = Math.round(asset.height / 2); // Create an Object to store CSS attributes css = { width : w, height : h, 'background-image' : "url(" + asset.image_1x_url + ")", 'background-size' : "" + asset.fullSize[0] + "px " + asset.fullSize[1] + "px", 'background-position': "-" + x + "px -" + y + "px" }; // If retina devices if (window.devicePixelRatio === 2) { /* set -webkit-image-set for 1x and 2x All the calculations of X, Y, WIDTH and HEIGHT is taken care by the browser */ css['background-image'] = "-webkit-image-set(url(" + asset.image_1x_url + ") 1x,"; css['background-image'] += "url(" + asset.image_2x_url + ") 2x)"; } // Set the CSS to the p p.css(css); };### 這是你如何使用它的程式碼:############
<br>
logo = new SSAsset( { fullSize : [1024, 1024], // image 1x dimensions Array [x,y] x : 1790, // asset x coordinate on SpriteSheet y : 603, // asset y coordinate on SpriteSheet width : 122, // asset width height : 150, // asset height image_1x_url : 'img/spritesheet_1x.png', // background image 1x URL image_2x_url : 'img/spritesheet_2x.png' // background image 2x URL },$('#logo'));### 在這裡下載完整的範例# 變像素密度,你可以看看Boris SMUS的這篇文章。 ######### ###3D內容管道############ 環境體驗建立於WebGL層上。當你想到一個3D場景,最棘手的問題之一是要如何確保你從建模,動畫和特效這些領域都可以創造出最有表現潛力的內容。從許多方面來說,這個問題的核心是內容管道:用一個定好的程式從3D場景來創建內容。 ###### 我們想創造一個令人振奮的世界,所以需要一個可靠的進程來幫助3D藝術家來創造它。他們將需要給予他們的三維建模和動畫軟體盡可能多的表達自由,而我們將需要透過程式碼將它們呈現在螢幕上。 ###
我們在這類問題上工作了一段時間,因為過去每次我們創建了一個3D網站,所以發現之前使用工具的一些限制。後來我們創造了這個被稱為3D Librarian的工具,正準備要把它應用到真正的工作上。
這個工具有歷史:它最初是為了Flash誕生的,它會允許你把一個大的Maya場景作為一個單一的壓縮檔案為拆包運行時進行優化。這是最優的原因是因為它有效的把場景包裝成基本上相同的資料結構,在渲染和動畫時進行操作。這樣在檔案載入時只需要做很少的解析。 Flash中的解包速度非常快,因為檔案是AMF格式,Flash能夠原生解壓縮。在WebGL中使用相同的格式,需要CPU多做一些工作。事實上,我們必須重新建立一個解壓縮資料JavaScript程式碼層,這基本上會將這些檔案解壓縮,並重新建立WebGL所需的資料結構。解壓縮整個3D場景是對CPU有一些負擔:解包遊戲的場景1在中高階機上需要約2秒鐘。所以為此我們在「場景設定」時間(實際上是場景出現之前)用Web Workers技術來實現,所以不會影響使用者的體驗。
這個方便的工具可以匯入3D場景:模型、紋理和骨骼動畫。你可以創建一個單一的庫文件,它稍後能被3D引擎所載入。
不過我們曾經遇到一個問題,現在用WebGL來處理。因此,我們創建了一個特定的JavaScript層,使用3D函式庫來壓縮3D場景文件,並將它們翻譯成正確的WebGL能理解的格式。
教學:有風
在「尋找奧茲之路」中一個反覆出現的主題是風。劇情的主線由弱到強的風所串起。
嘉年華的第一個場景相對平靜。經歷各種場景,使用者逐漸體驗強風,最後來到最終的場景,風暴中。
因此,重要的是提供一個身臨其境的風的效果。
為了達到這個效果,我們在3個嘉年華的場景中填滿較軟的對象,例如帳棚和氣球。
#
以上是如何開發優秀的HTML5遊戲-迪士尼《尋找奧茲之路》遊戲技術詳解(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!