2011年11月13日 星期日

一起來玩鳥 Starling Framework(3)Button!

週末夜來介紹個簡單的DisplayObject就好。不論是在電腦上或行動裝置上,跟使用者互動次數最多的,大概就是按鈕了。因此,Starling有個Button類別,來做出這個常用的互動元件。

同樣是因為由Sparrow移植過來的影響,Button的行為完全是行動裝置上的按鈕。它只有一個一般狀態的Texture,按鈕上的文字,以及壓下狀態的Texture(也可以不要)。事件只有一個:Event.TRIGGERED。沒有mouse over的狀態,也沒有useHandCursor可用。

Document Class依然不需要更動,再新增一個Game3.as當做Starling的rootClass,程式碼如下:
public class Game3 extends Sprite 
{
  private var _container:Sprite;
  private var _msgText:TextField;
  [Embed(source = "/assets/btnBg.png")]
  private static const BtnBitmap:Class;//embed一張圖片當做Button平常的狀態
  [Embed(source = "/assets/btnDownBg.png")]
  private static const BtnDownBitmap:Class;//embed一張圖片當做Button壓下的狀態

  public function Game3() 
  {
    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 menu:Sprite = new Sprite();//新增一個Sprite當做所有Button的容器
    menu.x = 100;//設定menu座標
    menu.y = 30;//設定menu座標
    _container.addChild(menu);//menu加到場景上
    _msgText = new TextField(300, 20, "No Button Triggered.", "Arial", 14, 0xFF0000, true);//新增一個TextField來顯示Button的狀態
    _msgText.x = 100;//設定_msgText座標
    _msgText.y = 80;//設定_msgText座標
    _msgText.hAlign = HAlign.LEFT;//設定_msgText文字靠左對齊
    _container.addChild(_msgText);//將_msgText加到場景上

    var btnTexture:Texture = Texture.fromBitmap(new BtnBitmap());//從embed圖片產生button平常狀態的Texture
    var btnDownTexture:Texture = Texture.fromBitmap(new BtnDownBitmap());//從embed圖片產生button壓下狀態的Texture
    var btnTexts:Vector.<String> = new Vector.<String>();//用一個Vector先將Button的文字存放起來
    btnTexts.push("About");//加入第一個Button文字
    btnTexts.push("Works");//加入第二個Button文字
    btnTexts.push("Video");//加入第三個Button文字
    btnTexts.push("Contact");//加入第四個Button文字
    var btnNum:uint = btnTexts.length;//Button個數
    var button:Button;//button用來當參照
    for (var i:int = 0; i < btnNum; i++)//用個迴圈設定四個button
    {
      button = new Button(btnTexture, btnTexts[i], btnDownTexture);//新增一個Button
      button.x = i * 150;//設定button座標
      button.name = "btn" + btnTexts[i];//設定button的name
      button.alphaWhenDisabled = 0.5;//如果button disable時alpha會自動變成0.5
      menu.addChild(button);將button加到場景上
    }
    button.enabled = false;//寫在迴圈外,我們故意將最後一個button disable
    menu.addEventListener(Event.TRIGGERED, buttonTriggered);//Event.TRIGGERED會bubble,所以只要對menu監聽就好
  }

  private function buttonTriggered(e:Event):void
  {
    _msgText.text = Button(e.target).name + " triggered!";//顯示哪個Button被triggered
  }
}

首先embed兩張圖分別當做Button的up state與down state時的Texture。然後先用一個Sprite menu當做容器,再將四個Button建立起來,放到這個容器裡面我們另外在場景上加了一個TextField用來顯示等等哪個Button被triggered的訊息。。Button有很多跟font有關的屬性可以設定文字的字型、字級、粗體等等來設定文字的樣式,如果配合BitmapFont就可以做出更多樣性的Button。關於BitmapFont之後再聊。加完四個Button後,我們故意將最後一個Button的enabled屬性設為false,用來觀察alphaWhenDisabled這個屬性的效果。這是當Button disable時,Button自動會改變自己的alpha值,直到恢復enable時,alpha會自動回到1。最後我們對加上menu加上Event.TRIGGERED監聽,因為這個事件預設是會bubble的,所以對外面的容器監聽就好。而事件發生時就會告訴我們哪個Button被triggered了。Event.TRIGGERED的發生跟MouseEvent.CLICK一樣,要在Button被按下,又在Button裡面放開時才會觸發。Demo如下:
點我或圖看Demo

上一篇:一起來玩鳥 Starling Framework(2)效能測試以及Image與Texture
下一篇:一起來玩鳥 Starling Framework(4)TouchEvent,Touch,以及TouchPhase

5 則留言:

  1. 為什麼Starling要實作自己的Button?

    回覆刪除
  2. 因為 Starling 的底層是用 Stage3D 製作
    使用的話,所以有的類別都要用他的
    Button 也是
    當然也可以用本來的 SimpleButton , 不過就不能加到 Starling 裡
    只能蓋在場景的最上層

    回覆刪除
  3. To Lu Rhino & milkmidi:
    是的,第一,Starling不只實作自己的Button,基本上整個繼承樹就只有最底層的Object跟原本的Flash是一樣的。第二,為什麼要實作Button這個類別,因為Button太常用啦,就跟當初為什麼Flash為什麼要有SimpleButton的道理差不多。因為從Sparrow移植回來的關係,Button的特性比較像行動裝置上的Button。
    另外,UI介面也可以考慮像奶綠說的,使用原本native的各種DisplayObject來作,可透過Starling.current.nativeOverlay 得到一個蓋在最上面的native Sprite,可以從這裡去加native的元件

    回覆刪除
  4. 若考慮到上下層的問題,那就沒辦法,除此之外我總覺得按鈕不太需要加速
    反正Strling的DisplayObject都可偵聽Touch事件(?)
    且Strling的Button的只能切換Texture,有點弱啊

    回覆刪除
  5. To Rhino:
    是的,以網頁來看Button其實有點弱,在手機上倒是很夠用了。其實我們也常常覺得native的SimpleButton不夠用,最後設計就用MovieClip來做MouseOver與MouseOut效果,再用程式來控制。Starling也一樣,例如我們可以用一個Sprite裝兩個Image,一個是一般狀態圖,一個是MouseOver圖,事件發生的時候使用Tween來改變兩張Image的Alpha,這樣至少有漸變效果了。若要更多的效果就需要有更多Tween的功能。只不過沒辦法用Flash IDE來做,只能用程式刻了

    回覆刪除