您在這裡

HTML5 遊戲框架:LimeJS

1 篇文章 / 0 新
HTML5 遊戲框架:LimeJS

不只是個遊戲開發套件。

相比於其他遊戲開發套件如《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 立馬挺槍啊。