繼 《LimeJS》基本介紹之後,來看 2D 遊戲幾乎都需要的 Sprite 動畫!
LimeJS 支援數種 Sprite 格式,亦能與多套 Sprite 製作工具銜接,但相關網路教學寫得較零碎,令人一時之間弄不清楚怎麼做才能順利顯示,本文嘗試兜一套作法作為 Demo。
先用專案工具開新範例 "fire",並清空自動產生的代碼。
指令:python bin\lime.py create fire
整理後的 fire.js 內容,留下環境設定與空白場景即可:
goog.provide('fire'); goog.require('lime.Director'); fire.W = 512; // 設定畫布寬高 fire.H = 512; // entrypoint fire.start = function(){ lime.scheduleManager.setDisplayRate(1000 / 60); // 60 FPS fire.director = new lime.Director(document.body, fire.W, fire.H); fire.director.setDisplayFPS(false); fire.director.makeMobileWebAppCapable(); s1(); }; var s1 = function(){ var scene = new lime.Scene(); fire.director.replaceScene(scene, lime.transitions.Dissolve); }; goog.exportSymbol('fire.start', fire.start);
首先準備動畫圖檔,手邊若缺素材,可先套用 Pow Studios 的火焰範例。
然後下載 Sprite 製作工具 TexturePacker,工具雖然要錢,但這裡只用免費功能來匯入圖片與設定 Sprite 相關參數便足夠了。使用方法如圖所示:
匯出格式選 cocos2d-original,這是 Limejs 支援的格式!
設定完成後,從選單 "File" 點 "Export Data" 以及 "Export Image",若之前路徑設定正確,我們應該可於專案內的 assets 目錄內發現兩個檔案:fireball_hit.plist 與 fireball_hit.png。前者為 Sprite 描述檔,後者為大張的 Sprite 圖。
是時候讓專案載入 Sprite 啦,LimeJS 準備了轉換工具協助我們自動載入,無需自行解析 Cocos2d XML Sprite。
指令:python bin\lime.py gensoy fire\assets\fireball_hit.plist
指令執行完畢於 assets 目錄產生兩個新檔案,soy 檔是樣板,js 檔則是載入器。
fireball_hit.plist.soy
fireball_hit.plist.soy.js
有了這兩個檔案就可直接於程式內引用 Sprite 資料!
把讀取代碼加入 fire.js
goog.provide('fire'); goog.require('lime.Director'); goog.require('lime.Scene'); goog.require('lime.Layer'); goog.require('lime.SpriteSheet'); // Sprite 工具物件 goog.require('lime.ASSETS.fireball_hit.plist') // 引用火焰動畫的描述資料 // ... 略 ... var s1 = function(){ var scene = new lime.Scene(); var layer = new lime.Layer().setPosition(0,0).setAnchorPoint(0,0); var bg = new lime.Sprite().setFill('#000').setPosition(0,0).setAnchorPoint(0,0).setSize(fire.W, fire.H); // 從圖檔與描述檔,取得 sprite 物件 var ss = new lime.SpriteSheet('assets/fireball_hit.png', lime.ASSETS.fireball_hit.plist, lime.parser.ZWOPTEX); // 抓 sprite 內的第一張圖來顯示,位置擺正中央 var sp = new lime.Sprite().setSize(100,100).setPosition(256,256).setFill(ss.getFrame('fireball_hit_0001.png')); layer.appendChild(bg); // 黑色背景 layer.appendChild(sp); // 火焰圖 scene.appendChild(layer); // 立即使用此場景 fire.director.replaceScene(scene, lime.transitions.Dissolve); }; goog.exportSymbol('fire.start', fire.start);
上述程式會從 Sprite 內撈出第一張靜態圖片 fireball_hit_0001.png,顯示於螢幕正中央。
至此 Sprite 資料結構其實已經全數載入,只是尚未用動畫的形式秀出來。我們利用 KeyframeAnimation 功能,將每一定格 (fireball_hit_0001.png ~ fireball_hit_0009.png) 的名稱加入並播放之。
var ss = new lime.SpriteSheet('assets/fireball_hit.png', lime.ASSETS.fireball_hit.plist, lime.parser.ZWOPTEX); var sp = new lime.Sprite().setSize(100,100).setPosition(256,256).setFill(ss.getFrame('fireball_hit_0001.png')); // 利用 Sprite 物件來建立 Animation var anim = new lime.animation.KeyframeAnimation(); for (var i=1; i<=9; i++){ anim.addFrame(ss.getFrame('fireball_hit_'+goog.string.padNumber(i,4)+'.png')); } sp.runAction(anim); anim.play();
完整 fire.js 代碼可見 github。若無意外,應能看見循環播放的火焰動畫如下。
最後記得編譯專案,才能放到網站。
指令:python bin\lime.py build fire -o fire\out\fire.js -a -p fire.start
我們需手動把 fireball_hit.png 放到輸出目錄的 assets 內,因為 LimeJS 並不會自動檢查代碼內引用哪些圖片。如果希望在程式開始執行之前預先載入此圖片,還要修改由編譯產生的 fire.manifest,寫入圖檔路徑,才算大功告成。
CACHE MANIFEST fire.js fire.html assets/startup.jpg assets/startup_ipad.jpg assets/icon.png # 加上圖片路徑 assets/fireball_hit.png NETWORK: *
只要找到合適的工具與格式,使用 Sprite 並不困難,主要把一些 Know-how 串起來即可。在下一篇系列文我們將結合 Sprite 與其他 LimeJS 功能,做個展示案例。