2011年11月17日 星期四

一起來玩鳥 Starling Framework(7)MovieClip

承上一篇,我們接著來講最後一個IAnimatable類別,MovieClip。Starling的MovieClip跟native的MovieClip不太一樣,它只能接收一個Vector.<Texture>,來指定每個frame的貼圖,而不能像native一樣當DisplayObjectContainer,加入一堆東西。不過透過一些工具,我們可以把native做好的MovieClip,輸出成一張Sprite sheet,以及一個XML檔,再將這張圖片與XML匯入Starling產生一個TextureAtlas,最後由這個TextureAtlas轉出Vector.<Texture>給MovieClip使用。

先來介紹一下產生Sprite sheet的工具,TexturePacker。這套軟體有Windows版與Mac版,可以輸出給很多framework使用。我們可以先下載Essential版來試用。下載安裝後,我們打開Flash Professional,新增一個movieClip.fla,隨便做一段動畫,然後發布movieClip.swf。接著我們打開TexturePacker,把movieClip.swf直接拖曳到面板的右邊區塊,或按上面的"Add Sprites"按鈕。在介面中間的區塊,就可以看到TexturePacker幫我們把movieClip.swf時間軸的動畫排成一張Sprite sheet。左邊的設定面版,我們只要設定Data Format為Sparrow,勾選Autosize與Allow free sizes大概就可以了。設定選項的位置如下圖:
接著按下上方的"Publish"按鈕,這時候會先跳出一個視窗,告訴我們用了一些功能是需要購買License才能正常使用,否則會隨機將兩張圖貼上奇怪的字。這邊我們先做測試,所以直接按Continue。接著會讓我們分別儲存Data file(XML)以及Texture file(PNG)。我們分別存成movieClip.xml與movieClip.png。

我們可以打開movieClip.xml看一下,root node為TextureAtlas,裡面有很多SubTexture,name應該都為"movieClip.swf/00xx",等等我們會需要透過這個name的命名方式把它們取出來。

接下來就可以進入程式的部分了,先把程式碼貼出來:
public class Game7 extends Sprite 
{
  private var _container:Sprite;
  [Embed(source = "/assets/movieClip.xml", mimeType="application/octet-stream")]
  private static const SpriteSheetXML:Class;//embed Sprite sheet data file
  [Embed(source = "/assets/movieClip.png")]
  private static const SpriteSheet:Class;//embed Sprite sheet
  [Embed(source = "/assets/pon.mp3")]
  private static const SoundPon:Class;//embed一個聲音檔

  public function Game7() 
  {
    super();
    addEventListener(Event.ADDED_TO_STAGE, init);
  }

  private function init(e:Event):void
  {
    removeEventListener(Event.ADDED_TO_STAGE, init);

    _container = new Sprite();
    addChild(_container);
    addChild(new Stats());

    var bitmap:Bitmap = new SpriteSheet();
    var texture:Texture = Texture.fromBitmap(bitmap);//將Sprite sheet轉成Texture
    var xml:XML = XML(new SpriteSheetXML());//產生一個Sprite sheet data的XML

    var textureAtlas:TextureAtlas = new TextureAtlas(texture, xml);//新增一個TextureAtlas,把texture與xml傳進去

    var frame:Vector.<Texture> = textureAtlas.getTextures("movieClip.swf/");//將textureAtlas裡名稱為"movieClip.swf/"開頭的SubTexture取出來
    var movieClip:MovieClip = new MovieClip(frame, 30);//新增一個MovieClip,第一個參數傳入剛產生的frame,第二個參數設定fps
    movieClip.x = 0;//設定movieClip座標
    movieClip.y = 0;//設定movieClip座標
    movieClip.setFrameDuration(0, 0.5);//我們可以設定某個frame的停留時間,frame數由0開始
    var soundPon:Sound = new SoundPon();//新增一個Sound
    movieClip.setFrameSound(18, soundPon);//我們可以設定某個frame播放聲音,frame數由0開始
    _container.addChild(movieClip);//將movieClip加到場景上
    Starling.juggler.add(movieClip);//最後別忘了加到Starling.juggler開始播放
  }
}

首先我們將movieClip.png與movieClip.xml embed進來。將圖片轉成texture,data存到xml,然後新增一個TextureAtlas,將texture與xml傳進去。接著用
textureAtlas.getTextures("movieClip.swf/")
把我們剛剛在movieClip.xml裡看到name開頭為"movieClip.swf/"的texture都取出來給frame。這時終於輪到MovieClip登場,新增一個MovieClip,第一個參數把剛剛的frame丟進去,第二個參數可以設定fps。

順便介紹兩個好用的method。第一個為setFrameDuration(),可以另外再設定某個影格的停留時間,影格數從0開始。而setFrameSound()可以設定播放到某影格時播放一個聲音檔。

最後,把movieClip加到場景上,並且記得加到Starling.juggle才會開始播放。Demo如下:
點我或圖看Demo

上一篇:一起來玩鳥 Starling Framework(6)Juggler、Tween、以及DelayCall
下一篇:一起來玩鳥 Starling Framework(8)BitmapFont

3 則留言:

  1. gray大,不好意思,小弟新手,請問什麼是Sprite sheet??為什麼都要用它?

    回覆刪除
  2. To Ricky:
    前面文章有提過,Starling顯示的原理,就是畫兩個三角形,再貼上材質,如此就能享受GPU加速的優勢。瞭解這原理之後,Sprite Sheet就是把好幾個我們要用到的材質整合成一張圖,這樣我們一次上傳到GPU會比較節省GPU的負擔,需要把某一塊貼圖取出來的時候,則需要XML裡面記錄的資訊。搜尋Sprite sheet你可以找到更多相關的資訊。

    回覆刪除
    回覆
    1. 原來如此,非常感謝!詳細解說!

      刪除