顯示具有 Adobe Flash 標籤的文章。 顯示所有文章
顯示具有 Adobe Flash 標籤的文章。 顯示所有文章

2013年1月28日 星期一

找不到iOS 裝置

作者在Windows 環境下, 使用Flash Builder 4.7 或Flash Professional CS6, 透過USB 連接iOS 裝置進行除錯發佈測試, 結果找不到任何iOS 裝置連接:

Flash Builder could not find a connected device.

以下是者作的電腦配置:
  • Windows 7 64 bit
  • iPad2 iOS 6.0
  • Flash Builder 4.7 或Flash Professional CS6 (Version 12.0.2.529) 更新請參考
  • Adobe AIR SDK 3.6
  • iTunes 11.0.1.12

在Goolge 找尋下, 發現一個方法可以暫時解決這個問題:
  1. C:\Program Files (x86)\Common Files\Apple\Apple Application Support\ 路徑, 找到SQLite3.dll
  2. SQLite3.dll 檔製至C:\Program Files\Adobe\Adobe Flash Builder 4.7 (64 Bit)\eclipse\plugins\com.adobe.flash.compiler_4.7.0.XXXXXX\AIRSDK\lib\aot\bin\iOSBin\

其實這個問題, 不是每個電腦會發生, 者作朋友的電腦在相同配置條件下, 亦不會遇上. 相信與電腦內曾安裝SQLite 軟件有關係.


後記:
對Flash Professional CS6 的用戶, 解決方法與Flash Builder 相似, 設定Adobe AIR SDK 請參考.

2013年1月17日 星期四

P2P 指令同步播放影片

作者製作一個處理Peer-to-peer(P2P) 的物件(P2PCore), 它透過Action Script 原生的NetConnectionNetGroup, 簡單地傳送文字, 圖像或物件, 達成點對點資料傳送.


以下為大家介紹, 如何利用P2P 技術, 在iPad 與PC 之間同步播放影片: 
  1. 建立P2PCore 物件, 為它加入監聽事件:
    var _core:P2PCore = new P2PCore();
    _core.addEventListener(P2PEvent.LOAD,loadHandler);
    _core.addEventListener(P2PEvent.MESSAGE, messageHandler);
    

  2. 當P2PCore 連接成功, 為用戶介面加入監聽事件:
    function loadHandler(event:P2PEvent):void{
      scaleX1Btn.addEventListener(MouseEvent.CLICK, scaleX1ClickHandler);
      scaleX2Btn.addEventListener(MouseEvent.CLICK, scaleX2ClickHandler);
      video.addEventListener("stateChange", playheadUpdateHandler);
    }
    

  3. 當按下Scale x1 或Scale x2 按鈕, 透過P2PCore 廣播給所有裝置改變影片大小:
    function scaleX1ClickHandler(event:MouseEvent):void{
      video.setScale(1, 1);
      _core.sendObject({type:"setScale", value:1});
    }
    function scaleX2ClickHandler(event:MouseEvent):void{
      video.setScale(2, 2);
      _core.sendObject({type:"setScale", value:2});
    }
    

  4. 當改變影片播放位置, 透過P2PCore 廣播給所有裝置最新播放位置:
    function playheadUpdateHandler(event:Event):void{
      _core.sendObject({type:"playheadTime", value:video.playheadTime.toString()});
      video.play();
    }
    

  5. 若裝置接收廣播訊息, 改變影片大小或播放位置:
    function messageHandler(event:P2PEvent):void{
      var msg:P2PMessage = event.value as P2PMessage;
      switch(msg.data.type){
        case "setScale":
          video.setScale(msg.data.value, msg.data.value);
        break;
        case "playheadTime":
          // <----- only allow one controller
          video.removeEventListener("stateChange", playheadUpdateHandler);
          
          video.playheadTime = parseFloat(msg.data.value);
          video.play();
        break;
      }
    }
這個實例主要運用發出和接收指令, 達到影片同步播放功能, WiFi 穩定性會直接影響iPad 與PC 之間的同步效果. 若希望製作串流影片, 請參考這個連結.

大家可以 [下載] 範例試試看.

注意事項:
 - 在Flash Professional CS6 透過USB 連接iOS 安裝發佈請參考這個連結.
 - Flash Media Server 我們可以申請Adobe 公開伺服器 (rtmfp://stratus.adobe.com/) 作試驗或自行架設.

2013年1月10日 星期四

Flash Professional CS6 透過USB 連接iOS 安裝發佈

在Flash Professional CS6 版本12.0.2.529 中, 我們可以透過USB 連接iOS 裝置, 進行實機測試. 在Windows 或MAC OS X 平台兩者皆可, 過程無需透過iTunes 或越獄(Jailbreak) 後的iOS 裝置, 純粹USB 連接, 十分方便.

以下是更新Flash Professional CS6 和連接iOS 發佈方法:
  1. 在官方下載最新Flash Professional CS6 更新:

  2. 安裝完成後, 在Help -> Aboout Adobe Flash Professional 看到新版本編號 (12.0.2.529).

  3. 下載Adobe AIR SDK, 然後設定路徑. (設定方法請參考)

  4. 開啟一個AIR for iOS  新專案.

  5. 設定發佈對象為AIR 3.4 for iOS 或以上版本.

  6. AIR for iOS Settings -> Deployment 中, 選擇以USB 連接iOS 裝置進行實機測試.
    (Install application on the connected iOS device)


注意事項:
若曾經修改host 檔案, 在更新過程會發生錯誤訊息, 請把host 檔案暫時回復, 待更新完成後才可修改.
(host 檔案路徑: C:\Windows\System32\drivers\etc\host)

2012年7月17日 星期二

Flash Daily 網頁介紹

Flash Daily 的作者, 收集不少關於Flash 示範, 內容十分豐富. 我們可以發現不少驚訝作品:

Hello Racer

+360º - Car Visualizer

Neema
還有許多Augmented Reality (AR), Kinect, 3D Engine... 等示範喔.

2012年6月10日 星期日

[教學] Flash 遊戲製作 (燒粟米)

這個範例, 為大家簡介在Flash 製作燒粟米遊戲, 並發佈於Android 和iOS 運行. 作者以基本設定自定物件兩部分說明遊戲製作技巧:

請按 [觀看] 範例
基本設定:
  • 場景(Scene) 流程: 在Window -> Other Panels -> Scene 中, 自由加入需要的場景.
    場景流程: Logo → Intro → Game Play → Game Over
     
  • 提升顯示速度: 把圖案轉換成JPG/PNG 等格式, 或啟動Cache as Bitmap.

  • 背景音樂(Background music): 把音樂放於時間軸上. 然後設定Sync: Stream, 這樣音樂與遊戲同步播放和停止. 其他的音效同樣可以這方式加入遊戲中.

  • 利用時間軸製作粟米狀態: 關於狀態顯示, 作者喜歡多用Flash 時間軸製作, 既簡單又實用.

自定物件:
遊戲中每一個物件, 我們會編寫繼承MovieClip, 它們成為獨特的物件, 在畫面負責一項功能, 與用戶產生互動. 範例製作以下幾個物件:
  • CornCooking 物件 - 遊戲框架, 把所有自定物件連繫一起.

    當加入新粟米時, 會執行addCorn 程序,  啟動粟米的拖拉(drag) 功能:
    public function addCorn(corn:Corn):void {
      // <----- start action
      corn.drag(this.stage);
      
      // <----- add listener
      corn.addEventListener(CornEvent.START_DRAG, startDragHandler);
      corn.addEventListener(CornEvent.STOP_DRAG, stopDragHandler);
    }
    

    當粟米被按動時, 若測試重疊於Oven 上, 會加入至爐中,
    否則會由Scoreboard 決定所得分數:
    private function stopDragHandler(event:CornEvent):void {
      var corn:Corn = event.target as Corn;
      var oven:CornOven = hitOven(corn);
      if (oven != null) {
        // <----- put to a oven
        oven.corn = corn;
        
      } else if (_scoreboard != null) {
        // <----- earn a score
        _scoreboard.addScore(corn);
        
        // <----- destory the corn
        corn.destory();
      }
    }
    

    測試重疊程序, 是利用內建的hitTestObject 功能作判斷:
    private function hitOven(corn:Corn):CornOven {
      for (var i:int = 0; i < _ovens.length; i++)
        if (corn.hitTestObject(_ovens[i]))
          if (_ovens[i].corn == null) // <----- is an available oven
            return _ovens[i];
      return null;
    }
    

  • CornOven 物件 - 火爐物件, 沒有實際顯示介面. 在遊戲中提供四個位置給用戶燃燒粟米.

    當粟米加入爐中, 會把粟米顯示於爐的中心位置, 和啟動粟米的燃燒(burn) 功能:
    public function set corn(value:Corn):void {
      if (_corn != null) {
        // <----- clear last corn
        _corn.removeEventListener(CornEvent.START_DRAG, startDragHandler);
        _corn.removeEventListener(CornEvent.DESTORY, destoryHandler);
      }
      
      if(value!=null){
        // <----- cache variable
        _corn = value;
        
        // <----- add to UI
        _corn.x = 0;
        _corn.y = 0;
        this.addChild(_corn);
        
        // <----- set action
        _corn.burn();
        
        // <----- add listener
        _corn.addEventListener(CornEvent.START_DRAG, startDragHandler);
        _corn.addEventListener(CornEvent.DESTORY, destoryHandler);
      }
    }
    

  • Corn 物件 - 粟米物件, 提供不同狀態顯示 .

    拖拉(drag) 功能是發動用戶的Mouse Down 與Mouse Up 的功能:
    public function drag(stage:Stage):void {
     // <----- cache variable
     _stage = stage;
     
     // <----- start to drag
     mouseDownHandler(null);
    }
    

    燃燒(burn) 功能是播放粟米在時間軸上的狀態:
    public function burn():void {
      if (this.currentFrame < this.totalFrames)
        this.play();
    }
    

  • CornScoreboard 物件 - 計分板, 處理粟米所得的分數, 和顯示總分數於螢幕右上方.

    提供addScore 程序, 當傳入一個粟米(Corn), 判斷將會得到的分數:
    public function addScore(corn:Corn):int {
      // <----- define variable
      var value:int = 0;
      
      // <----- earn a score from a corn
      switch(corn.status) {
        case Corn.STATUS_RAW:
          value = -10;
        break;
        case Corn.STATUS_BEGINNING:
          value = -5;
        break;
        case Corn.STATUS_MIDDLE:
          value = -1;
        break;
        case Corn.STATUS_GOOD:
          value = +10;
        break;
        case Corn.STATUS_FIRE:
          value = -10;
        break;
      }
      
      // <----- change the score
      _score += value;
      
      // <----- adjust value
      if (_score < 0)
        _score = 0;
      
      // <----- cache variable
      _lastScore = _score;
      
      // <----- set UI
      applyScore();
      
      // <----- dispatch event
      var e:CornEvent = new CornEvent(CornEvent.SCORING);
      e.value = value;
      this.dispatchEvent(e);
      
      // <----- return the value
      return value;
    }
    

  • CornScoring 物件 - 粟米得分效果.

    當加入得分效果, 呼叫applyScore 來判斷顯示的顏色:
    private function applyScore():void {
      if (_textField != null) {
        _textField.textColor = _score>0?0x009900:0x990000;
        _textField.text = (_score>0?"+":"")+_score.toString();
      }
    }
    

  • CornTimer 物件 - 計時物件.

    檢查時間軸是否完結, 然後發動GAME_OVER 事件給場景作改變:
    private function enterFrameHandler(event:Event):void {
      if (this.currentFrame == this.totalFrames) {
        // <----- stop UI
        this.stop();
        
        // <----- remove listener
        this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        
        // <----- dispatch event
        this.dispatchEvent(new CornEvent(CornEvent.GAME_OVER));
      }
    }
我們除燒粟米外, 加入更多圖案和關卡, 變成一個好玩的燒烤遊戲喔.
大家可以 [下載] 範例試試看.

2012年5月22日 星期二

右鍵點擊Right Click (Flash Player 11.2 新功能)

過去Flash 右鍵點擊 (Right Click), 會看到預設的右鍵選單 (ContextMenu).
現在我們可以去除這個功能, 在Flash Player 11.2 中, 以MouseEvent.RIGHT_CLICK 取代, 更為友善.

 請按 [觀看] (需安裝Flash Player 11.2)

若把整個Flash 內容的右鍵功能去除:
stage.addEventListener(MouseEvent.RIGHT_CLICK, function(e:Event){});

若把某MovieClip 的右鍵設定:
function someHandler(e:MouseEvent):void
{
  trace("right click");
}
someMovieClip.addEventListener(MouseEvent.RIGHT_CLICK, someHandler);

我們可以利用這功能, 簡單的隱藏她是一個Flash Player. 還可以自建一些右鍵功能, 效果相當理想.

參考資料: http://www.leebrimelow.com/?p=3337

2012年5月17日 星期四

Flash CS6 iOS/Andoird Simulator (CS6 新功能)

Flash CS6 支援Simulator 這個新功能, 不用發佈至iOS 或Android 裝置, 加速計(Accelerometer), 多點觸控(Touch and Gesture) 和地理位置(Geolocation) 給開發者利用Simulator 介面輸入所需數據, 模擬在裝置產生的數據.

Flash 內建的Accelerometer 範例

Flash 內建的Swipe Gallery 範例

大家在Flash 內建的New -> Templates -> AIR for Android 可以找到一些簡單範例作測試.

2012年5月16日 星期三

Manage AIR SDK (CS6 新功能)

在Flash CS6 加入新AIR SDK, 我們可以簡單在Manage AIR SDK 中設定:
  1. 下載Adobe LAB 最新AIR SDK

  2. SDK 解壓並存放於C:\Program Files\Adobe\Adobe Flash CS6

  3. 選擇Flash -> Help -> Manage AIR SDK

  4. 加入新增的SDK 路徑

  5. Properties -> Target 選擇最新的AIR SDK (現為AIR 3.3.0.3560 版本)

  6. Ctrl + Enter, 使用最新的AIR SDK 作測試對象
若果Adobe 再更新AIR SDK 時, 我們可以減少更新的麻煩喔.
較舊版本的Flash Professional CS5.5 安裝AIR SDK, 請參考這個設定.

參考資料: http://www.youtube.com/watch?v=qbrBrfOvmQ8

2012年5月15日 星期二

Generate Sprite Sheet (CS6 新功能)

較早之為大家介紹的TexturePacker, 為Starling 圖像引擎提供播放連續動作的Sprite Sheets 格式檔案. 現在的Flash CS6 中, 直接支援這個功能, 在Library 選擇所需的MovieClip, 然後按滑鼠右鍵, 點選Generate Sprite Sheet 便能產生Sprite Sheets 格式檔案.


Library 選擇MovieCLip
Generate Sprite Sheet 設定


若有興趣Starling 播放Sprite Sheets 檔案, 請瀏覽這個範例.


注意事項: 使用Starling 的getTextures 時, 請注意文字的大小階與Library 中MovieClip 的名字相同.

2011年11月16日 星期三

量度跑步速度App

在官方的Adobe TV 中, 會有一些教學影片, 簡單地完成範例.
以下的範例量度跑步速度, 利用Geolocation 物件, 產生的事件(GeolocationEvent.UPDATE), 它回傳的移動速度(event.speed). 配合一些簡單圖案和動畫, 便可製作出一個小小的App.






大家可以到Adobe TV, 會有一些範例可作參考.

2011年11月10日 星期四

Adobe 已經宣佈停止開發新的移動版 Flash Player

Adobe 已經宣佈停止開發新的移動版 Flash Player,將轉向 HTML5 技術發展的消息,並稱此次為公司一次重要的移動戰略布局改變,未來將會集中在 Adobe AIR 和跨平台移動應用上的發展,同時加大力度對 HTML5 進行研發。



筆者認為, 既然大多數使用者, 在移動平台上較喜歡使用Apps 多於瀏覽器(Browser). 原生Apps 是王道, Adobe 選擇放棄Web Site 這個戰略要點, 主力發展Adobe AIR, 亦不難理解. 不倚靠第三方平台(瀏覽器及OS 生產商), 這是當初Adobe AIR 出現目的, 打破被第三方平台控制局面. 未來發展方向, 將定位於硬體3D 與跨平台應用軟體為主.

資料來源: http://blogs.adobe.com/conversations/2011/11/flash-focus.html

2011年10月27日 星期四

動畫設計師(Designer) 製作Apps

對於動畫設計師(Designer), 開發手機程式, 一定是苦惱事情. 盡管掌握傳統開發方式, 把UI 介面和動畫設計完全整合, 也是一大難題, 不時經由程式員(Programmer) 恊助一同處理, 開發成本十分高昂.
  • 傳統開發 iOS App
      - 首要必須一部MAC OS X 電腦
      - 安裝Xcode 開發平台
      - 學會Objective-C 語言
  • 傳統開發 Android App
      - 安裝Eclipse 開發平台
      - 學會Java 語言

現在, 動畫設計師可以使用Adobe Flash, 直接開發手機程式, 不求人幫助下輕鬆完成. 技巧純粹過去製作Flash 動畫方法, 在時間軸(Timeline) 設定即可, 十分簡單.
  • 開發Adobe AIR
     - 安裝Adobe Flash Professional CS5.5
     - 學會Action Script 3.0 (兩三個指令足夠運作)
     - 發佈Android, BlackBerry Tablet OS 和 iOS 

以下為大家介紹一個iPad App 範例, 及講解一些注意事項.



提升速度功能 - Cache as Bitmap
Cache as Bitmap 功能對於提升畫面速度, 有顯著效果, 它在每一個Movie Clip 的屬性值可以設定. 但我們不是每一個Movie Clip 都啟動它, 因為一些情況下, 會出現反效果, 使速度減低.


  • 啟動Cache as Bitmap 情況:
    若Movie Clip 內是靜態內容, 而整個Movie Clip 又會移動的話 (如範例的背景移動), 我們應使用Cache as Bitmap 功能

  • 不應啟動Cache as Bitmap 情況:
    若Movie Clip 內容包含影像不斷更新 (如範例的蝴蝶), 請不要啟動Cache as Bitmap, 還要把它放至獨立的圖層(Layer) 中. 它們不應包含在任何Movie Clip 內, 避免影響其他已啟動Cache as Bitmap 的Movie Clip, 作不必要的連續渲染

呼叫父系(parent) Movie Clip
在Action Script 2.0 時代, 我們可以輕易使用this._parent 呼叫上一層的Movie Clip, 在Action Script 3.0 同樣可以簡單的呼叫. 我們把this.parent 回傳定義為MovieClip 類別, 然後便可以呼叫stop(), play(), gotoAndStop() 及gotoAndPlay().
(this.parent as MovieClip).gotoAndPlay("home");

按鈕事件
因為Action Script 3.0 統一事件處理手法, 我們必須定義Movie Clip 名字, 然後addEventListener 給它, 當用戶按下便會發動事件.
function btn1ClickHandler(event:MouseEvent):void{
 (this.parent as MovieClip).gotoAndPlay("about");
}
btn1.addEventListener(MouseEvent.CLICK, btn1ClickHandler);


開啟瀏覽器
過去Flash 連結至雅虎, 我們會寫getURL("http://yahoo.com");, 現在我們可以這樣寫:
navigateToURL(new URLRequest("http://yahoo.com/"));



大家可以 [下載], 然後一齊看看. 製作自己的手機Apps.
若發佈iOS App 作實機(iPhone/iPad) 測試, 請參考以下教學.

注意事項: 請確定已更新Adobe Flash Professional CS5.5 及Adobe AIR 2.7 或以上, 若不更新發佈時會出現問題.

2011年10月25日 星期二

HttpFox 檢視用戶端與伺服器之間內容

對於Flash 或AJAX  開發人員, 我們有需要向伺服器請求內容, 或傳送用戶資訊給伺服器. 透過Web Service, Servlet 或動態網頁語言(ASP, PHP...) 等方式作溝道橋樑. 過程往往在背後運作, 判定是否正確, 我們可以利用FireFox 瀏覽器中的免費擴充套件HttpFox.


啟動HttpFox 後, 瀏覽器所載入的內容, 一目了然的顯示出來, 包括Flash 所傳送的POST Data 內容.

伺服器回傳的內容, 同樣可以在當中清楚顯示.

若發佈後, 不幸遇到錯誤, 大家可以冷靜地, 打開HttpFox, 必定會給你一個答案.

2011年10月19日 星期三

[教學] 輸出PDF 文件

ALIVEPDF 是一個免費開源程式集, 用戶端使用Adobe Flash 直接輸出PDF 文件, 不需經由伺服器處理.
以下一個簡單範例, 介紹內建的FileReference 與外掛的ALIVEPDF 結合使用.

範例功能:
  1. 用戶瀏覽一個影像檔案
  2. 將影像檔案嵌入PDF 文件給用戶下載





使用類別:
  • FileReference - 提供一個可以在使用者電腦與伺服器之間上傳和下載檔案的工具
  • ByteArray位元組的封裝陣列, 瀏覽檔案的內容
  • org.alivepdf.pdf.PDF - 外掛程式庫, 可生產PDF 文件

範例說明:
  • 用戶瀏覽一個影像檔案
    定義一個FileReference 物件
    var _file:FileReference = new FileReference();
    
    當用戶按下"Select a Image", 利用FileReference 打開瀏覽檔案視窗
    function selectClickHandler(event:MouseEvent):void{
      // <----- open file browser
      _file.addEventListener(Event.SELECT, fileSelectHandler);
      _file.browse(getTypes());
    }
    selectBtn.addEventListener(MouseEvent.CLICK, selectClickHandler);
    
    載入已瀏覽檔案
    function fileSelectHandler(event:Event):void{
      // <----- load image raw data
      _file.addEventListener(Event.COMPLETE, loadCompleteHandler);
      _file.load();
    }
    
    檔案內容儲存為ByteArray 物件, 然後跳至下一版面
    function loadCompleteHandler(event:Event):void{
      // <----- cache image raw data
      _data = _file.data as ByteArray;
      
      // <----- goto save scene
      gotoAndPlay("save");
    }
    
    
    

  • 將影像檔案嵌入PDF 文件給用戶下載
    當用戶按下"Save as PDF", 建立PDF 物件, 把檔案嵌入, 最後利用FileReference 給用戶下載
    function saveClickHandler(event:MouseEvent):void{
      // <----- define variable
      var file:FileReference = new FileReference();
      var pdf:PDF = new PDF(Orientation.PORTRAIT, Unit.MM, Size.A4);
      var resize:Resize = new Resize(Mode.FIT_TO_PAGE,Position.CENTERED);
      
      // <----- create page
      pdf.addPage();
      pdf.addImageStream(_data, ColorSpace.DEVICE_RGB, resize);
      
      // <----- output PDF file
      file.save(pdf.save(Method.LOCAL), "output.pdf");
    }
    saveBtn.addEventListener(MouseEvent.CLICK, saveClickHandler);
    

大家可以 [下載], 然後一齊看看.
當然這個PDF 類別, 還可以嵌入文字和Flash 內的任何MovieCLip.

參考資料: http://alivepdf.bytearray.org/?p=20

注意事項: 透過FileReference.save 給用戶下載檔案, 函數內必須包含由Flash Player 產生的MouseEvent. 若在一段情況下, 程式不能任意呼叫FileReference.save.

2011年10月3日 星期一

[教學] Flash 支援瀏覽器上一頁、下一頁

當Web 2.0 面世後, 大大小小的網頁, 採用局部更新頁面. 瀏覽速度得以提升, 整合更為友善.
令使用習慣改變, 瀏覽器喪失基本功能. 上一頁與下一頁, 在應用AJAX 或Flash 是一件苦惱事情. 只有極少數網頁(Gmail 等等), 還照顧這個用戶習慣.

Flash 支援瀏覽器上一頁、下一頁, 我們可以使用jQuery history (不建議使用Really Simple History, 因為支援度和穩定性不足), 為大家介紹一個簡單範例:


範例功能:
  1. 在Flash 按下按鈕, 然後修改URL 路徑
  2. 按瀏覽器上一頁或下一頁, 在不更新頁面情況下, 改變Flash 內容
  3. 在瀏覽器輸入URL 路徑, Flash 的起始頁為該內容

請按 [觀看] 範例


範例使用的JavaScript 程式庫:

  • jquery-1.6.4.min.js - 因jquery.history plugin 是基於jQuery 建構成, 這個程式庫是必須
  • jquery.history.js - 支援瀏覽器上一頁與下一頁功能. 它支援的瀏覽器類型:
      - Internet Explorer 6, 7, and 8+
      - Safari 4 and 5+
      - Google Chrome 4+
  • swfobject.js - 在不同瀏覽器上, 提供插入SWF 一致方法


範例使用的Action Script 類別:



範例說明:

  • 當使用戶在Flash 按下"Page 4" 按鈕時

    在Action Script 層面, 收到Mouse 事件後, 我們呼叫外部JavaScript 的"addHistory"
    function clickP4Handler(event:MouseEvent):void{
      var location:String = "p4";
      ExternalInterface.call("addHistory", location);
      changeLocationHandler(location);
    }
    this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    

    在JavaScript 層面, 利用window.location 修改URL 路徑
    (請不要使用Flash 的navigatorToURL() 修改, 因每個瀏覽器解讀是不一致)
    function addHistory(location){
      window.location = "#"+location;
    }
    

  • 在Action Script 層面登錄"changeLocation", 提供給JavaScript 呼叫

    由於ExternalInterface 登錄, 必須等待Flash Player 在HTML 層面完成載入. 在Action Script 我們會不斷呼叫"checkFunction", 查詢是不否完成載入
    function enterFrameHandler(event:Event):void{
      if(ExternalInterface.call("checkFunction"))
        this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
      ExternalInterface.addCallback("changeLocation", changeLocationHandler);
    }
    this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    

    在JavaScript 層面, 測試Flash Player 是否完成載入
    function checkFunction(){
      return document.getElementById("jquery_history").changeLocation!=undefined;
    }
    

  • 最後, 當用戶按瀏覽器上一頁或下一頁

    在JavaScript 層面, 收到history 事件改變, 我們呼叫外部Action Script 的"changeLocation"
    jQuery(document).ready(function($) {
      function load(loc) {
        if(checkFunction())
          document.getElementById("jquery_history").changeLocation(loc);
        lastLocation = loc;
      }
      $.history.init(function(url) {
        load(url == "" ? "1" : url);
      });
      $('#ajax-links a').live('click', function(e) {
        var url = $(this).attr('href');
        url = url.replace(/^.*#/, '');
        $.history.load(url);
        return false;
      });
    });
    

    在Action Script 層面, "changeLocation" 把內容gotoAndStop 跳至合適位置
    function changeLocationHandler(location:String):void{
      switch(location){
        default:
        case "p1": contentMc.gotoAndStop(1); break;
        case "p2": contentMc.gotoAndStop(2); break;
        case "p3": contentMc.gotoAndStop(3); break;
        case "p4": contentMc.gotoAndStop(4); break;
      }
    }
範例可在Internet Explorer, Safari, Google Chrome, Firefox, Opera... 等等, 運作正常.
大家可以 [下載], 然後一齊看看, 做一個友善的Flash 平台.

2011年9月28日 星期三

介紹Flash 作品的平台

Flash Rocks
在Facebook 上開設的一個分享平台.
FWA
相信很多Flash 老手和設計師, 一定會在這兒留下不少腳印, 見證過無數出色作品的誕生.
Adobe & Mobile
以Web App 形式顯示, 大家可以使用手機瀏覽, 主力推廣Adobe Flash 及Adobe AIR 在流動電話平台.
Adobe 官方收藏館
官方收藏了不少作品, 可以找到不少高水準作品參考. 當中還展示以最新Adobe AIR Mobile 技術的作品.
ClockMaker.jp
日本PaperVision3D 的作品參考, 雖然內容較舊, 但Paper Vision3D 對硬體要求低, 是值得參考的網頁.

2011年9月17日 星期六

TweenLite 介紹

在一般情況下, 我們建議使用Flash IDE 來設計物件動畫.

  • 在時間軸(Timeline) 上設計, 可作細緻調整, 然後配合gotoAndPlay 跳至所需片段播放
  • 對於動畫設計師, 他們可以簡單利用Flash IDE 設計, 不需詳細理解程式內容


不過, 製作複雜動畫, 操控件物移動, 我們還會用上程式計算. 在Adobe Flash 內建的Tween 類別, 由於效能較差, 我們選擇另一個Tweening Engine 來完成工作.

  • TweenLite - 比內建類別速度快上很多, 用法十分簡單

    import com.greensock.*;
    TweenLite.to(mc, 1, {x:65, y:117});
    

以下為TweenLite 對不同引擎速度比較:



以下為TweenLite 程式碼產生器:



2011年9月14日 星期三

Flash 與HTML5 在電話運行速度

雖然Apple 公司在iOS 瀏覽器不提供Adobe Flash Player 支援, 她們提供HTML5 作為開發方案, 原因在於速度與穩定性上. 幸運地, 我們還有Google 公司的Android, 可以運行HTML5 及Flash, 給我們一個正確答案.

國外有很多朋友, 製作一些例子, 證明Flash 與HTML5 執行同一工作時, 它們有一定效能差距.
以下片段可以看到:




當然本人也同意, 現在很多Flash 在電話運行速度不順暢. 原因在於設計者當時, 純粹考慮在電腦運行, 電話仍然未曾普及, 沒有照顧電話硬件上限制.

不要因為Apple 某些公司, 說一些不負責任的說話, 而判定一些技術成敗.
參考資料: http://clockmaker.jp/blog-en/2010/10/butterfly-3d-canvas-javascript/

2011年9月11日 星期日

[教學] Flash 遊戲製作 (進階編)

以Adobe Flash 製作遊戲, 只要懂得幾個重點, 每個人都能編寫遊戲.
現在為大家介紹, 如何編寫簡單射擊遊戲, 我們會分兩部分說明 (基礎編 及 進階編).
  • 基礎編 - 為大家講解AS3(Action Script 3.0) 基本用法, 構成遊戲的基本元素, 用戶與遊戲之間溝通方法.
  • 進階編 - 把所有遊戲元素物件化, 建構整個遊戲, 最後發佈至iOS 運作.
了解AS3(Action Script 3.0) 基本用法後, 製作一個簡單遊戲, 只要動動腦筋便可完成.
但要有效維護, 減少錯誤發生, 便需要一個完善結構.

Adobe Flash 提供一個既簡單, 又直接方法, 實踐物件導向 (Object-oriented) 功效. 每一個物件可繼承MovieClip, 便可編寫成一個個獨特的物件, 在畫面出現, 彼此產生互動.

在Flash Library 中, 選擇一個合適物件, 然後設定Base Class, 把自行編寫的物件作連結, 這個物件便有著新的獨特功能.

我們可以想像畫面中, 出現的每一個元素, 把它們視為一個物件.
每一個物件有著它們特性(屬性Property 與方法Method), 然後把每個物件都串聯在一起.
現在為大家介紹, 以射擊遊戲作一個簡單說明.

範例功能:
  1. 開始畫面
  2. 遊戲畫面
      - 按下螢幕時, 移動玩家位置
      - 測試玩家是否被擊中
  3. 完結畫面




範例類別說明:
SimpleGame
  功能: 主管整個遊戲流程
  屬性: 擁有一個飛行空間(FlyingArea) 和一個分數版(Scoreboard)
  方法: 可跳至遊戲畫面和完結畫面

FlyingArea
  功能: 提供一個空間, 給所有飛行物件移動, 測試物件之間是否重疊碰撞
  屬性: 擁有多個飛行物件(FlyingObject) 和一個玩家物件(Plane)
  方法: 提供增加和破壞飛行物件

Scoreboard
  功能: 顯示和計算分數
  屬性: 擁有一個分數變數
  方法: 提供重新設定和增加分數

FlyingObject
  功能: 作為所有飛行物件的基礎物件, 所有繼承者都有著它的功能
  屬性: 擁有慣性(inertia) 和加速度(acceleration)
  方法: 提供設定慣性值和加速度方法

Bullet
  功能: 繼承飛行物件

Plane
  功能: 作為玩家和電腦的父係物件
  屬性: 是否自動發炮(autoFire) 和炮彈重射緩衝期(bulletBuffer)
  方法: 提供發射炮彈方法

PlanePlayer
  功能: 由玩家控制的飛行物件

PlaneComputer
  功能: 由電腦控制的飛行物件


範例說明:
當遊戲開始, FlyingArea 會產生一個ENTER_FRAME 事件, 在每一次更新, 會執行以下四個工作:
  • 清除已經離開畫面的飛行物件 (clearObjects)
    private function clearObjects():void {
      for (var i:int = 0; i < _objects.length; i++)
        if (!_availableArea.contains(_objects[i].x, _objects[i].y))
          destoryFlyingObject(i--);
    }
  • 測試飛行物件之間是否重疊碰撞 (hitTestObjects)
    private function hitTestObjects():void {
      // <----- hit test for bullet
      for (var i:int = 0; i < _objects.length; i++)
        for (var j:int = 0; j < _objects.length; j++)
          if(_objects[i]!=null && _objects[j]!=null)
          if (i!=j && _objects[i].hitTestObject(_objects[j]))
            if (_objects[i] is Bullet && _objects[j] is PlaneComputer) {
              destoryFlyingObject(i--);
              destoryFlyingObject(j--);
            }
      
      // <----- hit test for player
      for (var k:int = 0; k < _objects.length; k++)
        if(_objects[k]!=null && _player!=null)
          if (_objects[k].hitTestObject(_player))
            if (_objects[k] is PlaneComputer) {
              destoryFlyingObject(k--);
              _player.destory();
            }
    }
    
  • 按照特定時間產生電腦物件 (createComputer)
    private function createComputer():void {
      var object:FlyingObject;
      if (_currFrame % LAUNCH_COM1 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 1;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM2 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 2;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM3 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 3;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM4 == 0) {
        object = new (getDefinitionByName("PlaneComputer2") as Class)();
        object.x = this.stage.stageWidth;
        object.y = 0;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM5 == 0) {
        object = new (getDefinitionByName("PlaneComputer3") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight/5*(Math.floor(Math.random()*4)+1);
        addFlyingObject(object);
      }
    }
    
  • 更新所有飛行物件的位置 (refreshObjects)
    private function refreshObjects():void {
      for (var i:int = 0; i < _objects.length; i++)
        _objects[i].refresh();
      _player.refresh();
    }
當有物件被移除時, FlyingArea 會發動事件給SimpleGame 處理.
如果被移除的物件為電腦, 便會增加分數. 但被移除的物件為玩家, 便會執行遊戲完結.
public function removeHandler(event:FlyingEvent):void {
  if (event.data is PlaneComputer)
    _scoreboard.addScore();
  else if(event.data is PlanePlayer)
    gameover();
}

大家可以 [下載], 然後一齊看看, 動手製作簡單遊戲玩玩.