不只是個遊戲開發套件。
相比於其他遊戲開發套件如《Cocos2d-html5》、《Crafty》,《LimeJS》 並不急於將自己包裝成遊戲專用的程式架構,儘管自稱為遊戲框架,它其實更像一般用途的多媒體場景製作工具。
LimeJS 建立在知名工具 Google Closure Tools 之上,因此帶入許多相當好的特性,例如代碼易讀易懂、架構清楚、有專案管理工具、盡量簡化製作網頁所帶來的雜務。一般網頁專案為人所詬病的缺點不外乎檔案散亂、程式風格處處不同、以及失序的事件處理,這在 LimeJS 得到了救贖,我們有機會利用它堆出較大的互動程式、保持在 iDevices 也能正常運作。
官方提供的操作指引不錯,這裡只條列重點:
* 安裝前系統需要 Python、Git、SVN、Java 四種道具
* 抓原始碼解壓縮
* 自動完成安裝: python bin\lime.py init
* 建立新專案: python bin\lime.py create hello
* 編譯、匯出結果: python bin\lime.py build hello -o hello\out\hello.js -a -p hello.start
最後再把編譯產生的東西 (.js .html .manifest assets) 全部放到 Web Server 即可,例如 Dropbox Public 資料夾。如果直接編譯預設專案,應該會看到這個結果。
賞玩一下,試著縮放瀏覽器視窗看看,有沒有發現橘色的球跟畫布也同步縮放?
LimeJS 解決了做網頁很麻煩的縮放排版問題,相容於先進瀏覽器具備的「全螢幕顯示」功能,在 iDevice 上也正常運作!稍微解釋一下這有什麼好嗨的,通常我們做遊戲只考量特定幾種解析度,但做網站卻得考慮任意解析度,此乃 HTML 文本的天性,HTML 遊戲也當如此。苦悶的是縮放排版帶來很多跨瀏覽器、跨手機的雜碎問題,燒壞不少前端製作者的肝,LimeJS 幫我們自動搞定實在是佛心來著啊。
LimeJS 套件亦整合了 Box2D 物理引擎,實用性大增,可參考看看完成度較高的免費商業作品《Voodoo Friends》。
一如往常,用實際範例理解程式架構吧!
LimeJS 觀念相當直覺:場景包圖層,圖層包物件,物件有行為,再給導演換場景。如果專案取名為 hello,我們可在 hello.js 內寫 hello.start() 函式:
hello.W = 1024; hello.H = 768; hello.start = function(){ lime.scheduleManager.setDisplayRate(1000 / 60); // 60 FPS hello.director = new lime.Director(document.body, hello.W, hello.H); // 畫布寬高 hello.scene1(); // 切到場景一 hello.director.makeMobileWebAppCapable(); }
hello.start() 為程式進入點 (打開 hello.html 可查呼叫點),主要做環境設定工作,並呼叫 hello.scene1() 切換到自訂的場景。
我們接著在 hello.scene1() 逐步累積場景一的內容。
hello.scene1 = function(){ var scene = new lime.Scene(); // setAnchorPoint 指定物件的左上角為座標原點 var layer = new lime.Layer().setPosition(0,0).setAnchorPoint(0,0); var bg = new lime.Sprite().setFill('assets/wood.jpg').setPosition(0,0).setAnchorPoint(0,0); var title = new lime.Label().setText('').setPosition(900,50).setFontColor('#fff').setFontSize(26) layer.appendChild(bg); // 背景 Sprite 塞給圖層 layer.appendChild(title); // 標題 Label 也塞給圖層 scene.appendChild(layer); // 圖層塞場景 // 用漸進轉場特效進入此場景! hello.director.replaceScene(scene, lime.transitions.Dissolve); };
這樣的場景只夠顯示木頭背景圖,來點星星吧!
function addStar(){ var x = Math.random()*hello.W; var y = Math.random()*hello.H; var star = new lime.Sprite().setSize(101,85).setFill('assets/star.gif').setPosition(x,y); layer.appendChild(star); } for (var k = 0; k < 10; ++k) addStar();
將上述代碼插入 hello.scene1(),代表要添加若干個星星物件到圖層,位置隨機。若星星圖片為 gif 動畫,它也會自動播放,使我們的畫面變成十顆星星轉啊轉的。
OK,記得蘑菇人方吉嗎?我們修改一下 addStar(),讓滑鼠掃過星星時可以吃掉它
// ...... // 每個星星物件掛上 mouseover、touch 事件 goog.events.listen(star, ['mouseover','touchstart'], function(e){ // 吃過的星星不重複吃 if (star.toBeDeleted) return; star.toBeDeleted = true; // 加分,並顯示於標題 score++; title.setText('Score: '+score); }); layer.appendChild(star); // ......
吃星星忘了改變畫面?加動畫吧!
goog.events.listen(star, ['mouseover','touchstart'], function(e){ if (star.toBeDeleted) return; star.toBeDeleted = true; // 放大並淡出的動畫,持續 1.5 秒 var zoomout = new lime.animation.Spawn( new lime.animation.ScaleTo(5), new lime.animation.FadeTo(0) ).setDuration(1.5); star.runAction(zoomout); score++; title.setText('Score: '+score); });
太安靜?加個吃星星音效!
// 進入場景時加載音效檔 var snd = new lime.audio.Audio('assets/pick.mp3'); goog.events.listen(snd.baseElement,"ended",function(){ snd.stop(); // 播放倒底時 reset 聲音物件 }); var score = 0; function addStar(){ var x = Math.random()*hello.W; var y = Math.random()*hello.H; var star = new lime.Sprite().setSize(101,85).setFill('assets/star.gif').setPosition(x,y); goog.events.listen(star, ['mouseover','touchstart'], function(e){ if (star.toBeDeleted) return; star.toBeDeleted = true; // 撥動畫 var zoomout = new lime.animation.Spawn( new lime.animation.ScaleTo(5), new lime.animation.FadeTo(0) ).setDuration(1.5).enableOptimizations(); star.runAction(zoomout); // 放音效! snd.play(); // ......
不知不覺音效、動畫、互動都有了... 超簡單,最後再弄個破關畫面吧,造場景二當做破關畫面。
hello.scene1 = function(){ // ..... goog.events.listen(star, ['mouseover','touchstart'], function(e){ // 在吃星星行為的末端做檢查,吃到第10顆就呼叫場景二! if (score>9) hello.scene2(); }); // ..... }; hello.scene2 = function(){ // 白底黑字 Game Over XD var scene = new lime.Scene(); var layer = new lime.Layer().setPosition(0,0).setAnchorPoint(0,0); var bg = new lime.Sprite().setFill('#FFF').setPosition(0,0).setAnchorPoint(0,0); var title = new lime.Label().setText('Game Over').setPosition(hello.W/2,hello.H/2).setFontColor('#000').setFontSize(64) layer.appendChild(bg); layer.appendChild(title); scene.appendChild(layer); hello.director.replaceScene(scene, lime.transitions.Dissolve); };
大功告成,程式執行如下 (好像太容易了點 XD)
片段式程式解說可能不太好記,將 hello.js 全兜起來比較好閱讀,或著整包抓回去檢視一下素材、程式、與網頁之間的關聯性。整包內附的 hello.js 已經通過 LimeJS 內附的建置工具最佳化,一堆亂碼為正常,要放到 Web Server 才能用瀏覽器執行。
經過多方實測,星星範例在手機、桌機、各種瀏覽器都能跑,包含 IE!可惜目前最新版的 Chrome 21 星星動畫有點異常。不過 LimeJS 專案已有相關 issue,相信過一陣子 LimeJS 團隊或 Chrome 團隊會修正相容性的問題。
LimeJS 的介紹就到這,多寫幾個場景 (Level),Prototype 立馬挺槍啊。