2012年8月30日 星期四

[教學] 安裝Adobe Alchemy 在MAC OS X

Adobe 在2009 年的研究項目中, 曾經被喻為劃時代的Adobe Alchemy, 開發者以C/C++ 編寫核心, 給ActionScript 調用, 達至加速效果. 回到今天運作平台分裂嚴重, 對我們現在Windows, MAC, Android 及iOS 同樣可以分享, 當年這個技術實在意義重大.

Adobe Alchemy 基於LLVM 技術運行

現在為大家說明如何在MAC OS X 環境中, 運用Adobe Alchemy 編譯C/C++ 語言, 包裝給ActionScript 調用.

必須有以下的準備:

安裝步聚:
  1. 把Flash Builder 內的SDK bin 目錄設定為MAC OS X 的PATH 環境變數(PATH Environment Variables)
     - 打開.bash_profile 檔案, 在Terminal 輸入:
          touch ~/.bash_profile; open ~/.bash_profile
     - 在TextEdit 中, 把空白的.bash_profile 檔案更改成:
         (請把Adobe Flash Builder 4.6/4.6.0_AIR3.4 更改成正確路徑)
          PATH="$PATH:/Applications/Adobe Flash Builder 4.6/sdks/4.6.0_AIR3.4/bin"
          export PATH

     - 在TextEdit 中把.bash_profile 檔案儲存(Command+S)
     - 然後在Terminal 輸入:
          source ~/.bash_profile
    - 關閉Terminal (Command+Q)
  2. 測試是否設定正確, 重新開啟Terminal, 然後輸入:
      adt -version
    若步聚正確, 會顯示SDK 版本代號"3.4.0.3010"
  3. 把下載的Alchemy Toolkit Package 解壓存放於/Library/alchemy/
  4. 把游漂移至alchemy 目錄內, 在Terminal 輸入:
      cd /Library/alchemy
  5. 執行alchemy 目錄內的config, 在Terminal 輸入:
      ./config
  6. 在PATH 環境變數加入alchemy 相關資料:
     - 再次打開.bash_profile 檔案, 在Terminal 輸入:
          touch ~/.bash_profile; open ~/.bash_profile
     - 在TextEdit 中, 把.bash_profile 檔案更改成:
         source "/Library/alchemy/alchemy-setup"
         PATH="$PATH:/Applications/Adobe Flash Builder 4.6/sdks/4.6.0_AIR3.4/bin"
         PATH="$PATH:/Library/alchemy/achacks"
         export PATH

     - 在TextEdit 中把.bash_profile 檔案儲存(Command+S)
     - 然後在Terminal 輸入:
          source ~/.bash_profile
     - 關閉Terminal (Command+Q)
  7. 重新開啟Terminal, 分別輸入:
      alc-on

      gcc
    以上兩個指令, 不會出現"command not found" 錯誤訊息, 代表設定完成

範例編譯:

  1. 把游漂移至alchemy/samples/stringecho/ 目錄內, 在Terminal 輸入:
      cd /Library/alchemy/samples/stringecho/
  2. 在Terminal 輸入:
      alc-on; which gcc
    以上指令會顯示出gcc 路徑"/Library/alchemy/achacks/gcc"
  3. 把c 語言編譯成swc 元件, 在Terminal 輸入:
      gcc stringecho.c -O3 -Wall -swc -o stringecho.swc
  4. 若元件正確產生, 在Terminal 會顯示以下訊息: (若發生錯誤, 請看編譯錯誤修正)
    1911.achacks.swf, 259831 bytes written
    frame rate: 60
    frame count: 1
    69 : 4
    72 : 259761
    76 : 33
    1 : 0
    0 : 0
    frame rate: 24
    frame count: 1
    69 : 4
    77 : 506
    64 : 31
    63 : 16
    65 : 4
    9 : 3
    41 : 26
    82 : 471
    1 : 0
    0 : 0
      adding: catalog.xml (deflated 75%)
      adding: library.swf (deflated 70%)

編譯錯誤修正:

修正一
  • 若在編譯時, 出現以下錯誤:
    Array @ARGV missing the @ in argument 1 of shift() at /Library/alchemy/achacks/gcc line 218.
    我們需以在/Library/alchemy/achacks 的gcc 檔案的218 行, 加入"@"字元, 請更改成:
    { $path = shift(@ARGV) }

修正二
  • 若在編譯時, 出現以下錯誤:
    dyld: Library not loaded: /usr/lib/libltdl.3.dylib
      Referenced from: /Library/alchemy/bin/llvm-gcc
      Reason: image not found

    我們需要把游漂移至/usr/lib/ 目錄內, 在Terminal 輸入:
      cd /usr/lib/
    然後再在Terminal 輸入:
      sudo ln -s libltdl.7.dylib libltdl.3.dylib

使用swc 元件:

我們透過Adobe Alchermy 成功產生swc 元件, 在Flash Builder 設定swc 路徑後, 便可以使用:
package
{
  import flash.display.Sprite;
  import cmodule.stringecho.CLibInit;
  
  public class stringecho_mobile extends Sprite
  {
    public function stringecho_mobile()
    {
      var loader:CLibInit = new CLibInit;
      var lib:Object = loader.init();
      trace(lib.echo("foo"));
    }
  }
}

大家若在Windows 環境下安裝Alchemy, 請參考這個連結, 安裝原理與MAC 很相近.

Alchermy 安裝參考:
http://labs.adobe.com/wiki/index.php/Alchemy:Documentation:Getting_Started
更改PATH 環境變數參考:
http://hathaway.cc/2008/06/how-to-edit-your-path-environment-variables-on-mac-os-x/
編譯錯誤修正參考:
http://forums.adobe.com/message/3892045

2012年8月29日 星期三

Flash Builder 4.7 beta

Adobe Lab, 我們可以免費下載最新Flash Builder 4.7 beta 版. 這版本支援Adobe AIR 3.4 以下兩個功能:
  • 以USB 連接iOS 裝置部署(deployment) 和除錯(debugging)
  • 或發佈於Xcode 中的iOS simulator 運作 (只限MAC OS X)



由於Flash Builder 4.7 beta 版不是內置Adobe AIR 3.4, 我們需要作以下設定:
  1. 下載Flash Builder 4.7 beta 版和完成安裝
  2. 下載Adobe AIR 3.4 SDK
  3. 對MAC OS X 使用者, 請參考這個SDK 設定. (若Windows 使用者請參考這個)
  4. 最後, 我們在Run -> Run Configurations -> Mobile Application 找到新的設定介面, 在<Choose launch method> 可以選擇三個方式發佈:
     - On AIR Simulator
     - On iOS Simulator
     - On device

Flash Builder 4.7 在發佈上的優化, 對開發者帶來方便, 實在是一件好事.
關於認證檔(Certificate) 和描述檔(Provisioning file) 設定大家可以參考這個.

2012年8月27日 星期一

MadComponents 元件

在Stage3D 技術發展下, 我們會找到很多相關應用, 在UI 元件也分享到硬體加速的成果. MadComponents 是其中一個在免費的框架, 目的是在iOS 或Android 以同一個UI 操作介面, 透過Stage3D 技術流暢運作.

請按 [觀看] 範例一
請按 [觀看] 範例二

開發人員主要透過XML 作介面設定, 我們來個簡單的Hello World 示範: [下載]

package
{
  import com.danielfreeman.madcomponents.UI;
  
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  
  [SWF(backgroundColor="#ffffff", frameRate="60", quality="LOW")]
  public class madcomponents_test01 extends Sprite
  {
    protected static const HOME_VIEW:XML = <vertical>
                        <label>Hello, World!</label>
                        <button>Continue</button>
                         </vertical>;  
    
    public function madcomponents_test01()
    {
      super();
      
      stage.align = StageAlign.TOP_LEFT;
      stage.scaleMode = StageScaleMode.NO_SCALE;
      
      UI.create(this, HOME_VIEW);
    }
  }
}

MadComponents 還有很多實用元件, 在官方的文件教程(Tutorial) 中有詳細說明:


以下是官方提供己利用MadComponents 框架製作, 並發佈於App Store 和Google Play 中的程式:
대전맞고 온라인 고스톱
The Etiquette App
Actionary
SimsUShare Mobile Lite

在Adobe AIR 發展領域, 跨平台的高效能元件, 相信會是其中的一個優勢.
除了Appcelerator Titanium 以javascript 作編寫語言, 然後編譯成源生元件. 我們還可以選擇MadComponents.

API 參考: http://e2easy.byethost9.com/madcomponents/

2012年8月25日 星期六

3D 引擊與Starling Framework 整合

最近, 一些3D 引擎對應Starling Framework 作出整合, 同時於兩個框架下渲染畫面.


Away3D 範例:
[範例一] Away3D Starling Layering Demo

請按 [Flare3D] 範例

這個整合彼此互保不足. 例如在3D 世界使用2D 粒子(Particle), 大大增加顯示效能, 同樣得到相似顯示. 還有很多內容我們可以選擇較有效率的2D 作顯示方式喔.

Away3D 整合教學: http://www.away3d.com/example/away3d_4.0_and_starling_interoperation

2012年8月24日 星期五

Minko 3D 引擊

關於Stage3D 這個功能, 越來越多公司參與研製相關的3D 引擎配合, 這個市場相當成熟.
其中法國公司Aerys 的3D 引擎Minko, 表現十分出色.

請按 [Black Sun] 試玩遊戲

請按 [觀看] 範例 (使用3D 物理引擎JiglibFlash)

除了選擇Away3D 與Alternativa3d 兩巨頭, 在一些開發人員的網頁, 我們可以找到Minko 蹤影.
大家希望對Minko 多一點了解, 可以到JEAN-MARC LE ROUX 觀看更多教學.

2012年8月23日 星期四

D'Fusion 的Augmented Reality 引擎介紹

在找尋Augmented Reality (AR) 引擎時, 作者找到一家TOTAL IMMERSION 公司, 她多年來主力發展AR 業務. D'Fusion 是其中一個產品, 能在Flash Player 或Adobe AIR 運行AR 引擎.

請按蝙蝠俠觀看範例 (iOS 版本)

請按MISTER SPEX 觀看範例

在TOTAL IMMERSION 網頁中, 我們會找到很多出色的AR 作品, 這家公司確實很強.
可惜現時D'Fusion SDK For Adobe Flash 不是對外開放. 有興趣的朋友, 可以嘗試聯絡她們.

2012年8月22日 星期三

啫喱物理引擎 jelloas3

啫喱狀態的物理引擎jelloas3, 是由Microsoft XNA 的JelloPhysics 改編成ActionScript 版本.

請按 [觀看] 範例

這個引擎效果十分有趣, 若可以簡單地給開發人員配合Stage3D 使用, 必定很實用喔.

Box2D Flash Alchemy Port 介紹

Box2D 是一個很出名的2D 物理引擎, 有C++, Java, ActionScript 等版本. 我們在開發Adobe AIR 或Flash 程式時, 除了選擇ActionScript 版本, 還可以使用Box2D Flash Alchemy Port 版本. 這是一個經由Adobe Alchemy 編譯的C++ 源生程式庫, 若要求極高計算效能時, 它是一個好選擇.



請按 [觀看] 示範

請按 [觀看] 示範

由於World Construction Kit 是透過傳統Flash IDE 建立物理世界, 在Android 或iOS 渲染速度會很慢. 我們必須使用Stage3D 硬體加速顯示, 利用Starling Framework 等引擎作為顯示框架.

2012年8月20日 星期一

[教學] Flash 遊戲製作 (憤怒豬 Angry Pig)

為大家介紹如何在Adobe AIR 編寫憤怒的小鳥(Angry Birds) 遊戲. 者作製作一個簡單範例 - 憤怒豬(Angry Pig), 以Starling 圖像引擎Nape 物理引擎完成.

請按 [觀看] 範例

遊戲內容與物理盒子遊戲相近, 不同在於處理以下事件(Event) 的內容:
  • MouseEvent.MOUSE_DOWN 時, 若用戶按在_pigImg 上, 把_dragFlag 設定true
    private function downHandler(event:MouseEvent):void{
      var mp:Vec2 = new Vec2(event.stageX, event.stageY);
      var bodies:BodyList = _space.bodiesUnderPoint(mp);
      
      // <----- start the launching action
      if(bodies.length > 0){
        var b:Body = bodies.shift();
        if(b==_pigImg)
          _dragFlag = true;
      }
    }
    
  • MouseEvent.MOUSE_UP 時, 若_pigImg 存在和_dragFlagtrue:
     - 建立_pig 於Nape 物理世界中
     - 以用戶手指與憤怒豬(_pigImg) 原來位置的距離乘以十倍, 設定_pig 拋出的速度 (velocity)
     - 移除_pigImg 這個圖案 (它是沒有物理效果)
     - 重設_historyData 路徑記錄

    private function upHandler(event:MouseEvent):void{
      if(_pigImg!=null && _dragFlag){
        var mp:Vec2 = new Vec2(_ns.mouseX, _ns.mouseY);
        var b:Vec2 = mp.subeq(_pigPosition);
        
        // <----- add a pig to physical world
        _pig = addPig(_ns.mouseX, _ns.mouseY);
        _pig.velocity = new Vec2(-b.x*10, -b.y*10);
        
        // <----- remove the launching pig
        this.removeChild(_pigImg.graphic);
        _pigImg.shapes.clear();
        
        // <----- reset paths of history
        _historyData = new Vector.<HistoryData>;
      }
      
      // <----- stop the launching action
      _dragFlag = false;
    }
    
  • Event.ENTER_FRAME 時, 我們進行以下測試和行為:
     - 若_historyData 路徑記錄存在:
        - 把路徑以QuadBatch 方式批次渲染於螢幕上
        - 然後把最後的路徑記下 (最多記錄30 個)
     - 若_dragFlagtrue, 把_pigImg 圖案移至用戶手指的位置上
     - 若_pig 存在, 測試它是否正在移動, 若接近停頓狀態, 重設_pigImg
     - 最後, 假如星星_star 移動速度大於一個數值, 遊戲便可完成
    private function enterFrameHandler(event:Event):void{
      // <----- run nape physical engine
      _space.step(1/60);
      
      if(_historyContainer!=null){
        // <----- reset history container
        _historyContainer.reset();
        
        // <----- draw paths to history container
        for(var i:int=_historyData.length-1; i>=0; i--){
          _historyImage.x = _historyData[i].x;
          _historyImage.y = _historyData[i].y;
          _historyImage.alpha = 1-i/_historyData.length;
          _historyContainer.addImage(_historyImage);
        }
        
        // <----- save the latest path
        if(_historyData.length<30 && _pig!=null){
          var historyData:HistoryData = new HistoryData();
          historyData.x = _pig.position.x
          historyData.y = _pig.position.y;
          _historyData.push(historyData);
        }
      }
      
      // <----- draw the launching position
      if(_dragFlag){
        var mp:Vec2 = new Vec2(_ns.mouseX, _ns.mouseY);
        _pigImg.position.set(mp);
      }
      
      // <----- kill the pig, if it stops
      if(_pig!=null && _star!=null){
        var v:Number = Math.abs(_pig.velocity.x)+Math.abs(_pig.velocity.y);
        if(v<50 || _pig.velocity.angle==0){
          this.removeChild(_pig.graphic);
          _pig.shapes.clear();
          _pig = null;
          _pigImg = addPigImage(_pigPosition.x, _pigPosition.y);
        }
      }
      
      // <----- game over, if the star is hitted
      if(_star!=null){
        var v2:Number =Math.abs(_star.velocity.x)+Math.abs(_star.velocity.y);
        if(v2>100 && _pig!=null){
          _star = null;
          this.dispatchEvent(new Event(Event.COMPLETE));
        }
      }
    }
    
當然製作一個成功遊戲, 需要很多配合(如: 遊戲流程, 角色設計, 場景設計, 測試優化, 市場推廣... 等). 但遊戲的核心部分, 不是一個困難, 重點在於創意與技術結合成一件產品喔.

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

2012年8月15日 星期三

Starling 批次加速

Starling 模仿Flash 傳統畫家算法顯示列表, 渲染方式以Stage3D 硬體加速. 開發人員透過MovieClip 形式建立結構, 並獲得Stage3D 的強大速度. 若大家對渲染速度有更高要求, 可以使用QuadBatch 批次渲染. 者作以Sprite Sheets 格式播放企鵝動畫, 分別以MovieClip 和QuadBatch 形式測試以下範例:

請按 [觀看] MovieClip 效能範例
請按 [觀看] QuadBatch 效能範例

在使用QuadBatch 時, 我們需要以下手法編寫:
  • Event.ADDED_TO_STAGE 時, 建立Image 作為渲染時的圖案庫和建立QuadBatch:
    private function init(event:Event):void{
      ......
      addEventListener(Event.ENTER_FRAME, enterFrameHandler);
      
      // <----- create textures
      var texture:Texture = Texture.fromBitmap(new AtlasTexture());
      var xml:XML = XML(new AtlasXML());
      var atlas:TextureAtlas = new TextureAtlas(texture, xml);
      var textures:Vector.<Texture> = atlas.getTextures("penguin");
      
      // <----- define variable
      _images = new Vector.<Image>;
      _mcData = new Vector.<MCData>;
      
      // <----- create images
      for(var i:int=0; i<textures.length; i++){
        _images[i] = new Image(textures[i]);
        _images[i].scaleX = TEXTURE_SCALE;
        _images[i].scaleY = TEXTURE_SCALE;
      }
      
      // <----- define container
      _quadBatch = new QuadBatch();
      this.addChild(_quadBatch);
      ......
    }
    

  • 當用戶按下螢幕, 增加100 隻企鵝, 並把位置記在自定的MCData 物件中:
    private function addPenguins():void{
      // <----- find max width & height
      var maxWidth:int = this.stage.stageWidth;
      var maxHeight:int = this.stage.stageHeight;
      
      // <----- move to random position
      for(var i:int=0; i<100; i++){
        var mcData:MCData = new MCData();
        mcData.x = maxWidth*Math.random()-TEXTURE_HALF_WIDTH;
        mcData.y = maxHeight*Math.random()-TEXTURE_HALF_HEIGHT;
        mcData.currentFrame = 0;
        _mcData.push(mcData);
      }
      ......
    }
    

  • 在每次發動Event.ENTER_FRAME 時, 重新渲染一次QuadBatch: (每1 秒60 次渲染)
    private function enterFrameHandler(event:Event):void{
      // <----- reset QuadBatch
      _quadBatch.reset();
      
      // <----- create image
      var image:Image;
      
      // <----- add image to QuadBatch
      for(var i:int=0; i<_mcData.length; i++){
        image = _images[(++_mcData[i].currentFrame)%TEXTURE_TOTAL_FRAMES];
        image.x = _mcData[i].x;
        image.y = _mcData[i].y;
        _quadBatch.addImage(image);
      }
    }
    

範例可於iPhone, iPad 及Android 測試效能. 觀察每個硬體對Starling 渲染的能力.
Starling 的QuadBatch 批次渲染速度, 明顯比MovieClip 形式更為高速, 但使用上較為複雜.
大家可以 [下載] 範例試試看.

參考資料: http://www.starlinglib.com/wiki/News:2DAnimationsOptimization

2012年8月13日 星期一

AR 遙控直昇機

國外一名高手David Salvatori 利用日本的AR 引擎FLARToolKit, 配合Papervision3D 模型引擎製作一個遙控直昇機示範. 以下短片展示不錯效果:


遙控直昇機練習: http://davidsalvatori.com/projects/ar/pv3d-helicopter/
AR Marker 下載: http://davidsalvatori.com/projects/ar/a4-helicopter.pdf
AR 遙控直昇機: http://davidsalvatori.com/projects/ar/bin/ (好像不太受控)

雖然這個是兩年前的作品, 但創意十分高, 值得我們參考.
相信以今天Stage3D 硬體加速技術(如Away3D 引擎) 製作, 效果必然更好喔.

參考來源: http://www.davidsalvatori.com/augmented-reality-with-actionscript3-realta-aumentata-con-actionscript-3/