2007年9月28日 星期五

AS3 影格控制與時間軸預置物件的問題   [+/-]

Ticore's Blog

ActionScript 3.0 的時間軸預置物件 (Timeline-Placed DisplayObject) 有一個很怪異的問題
當用 AS3 控制 MovieClip 跳格之後,沒有辦法立即取得新影格上預先放置的物件
必須要等到下一個 Frame 才可以取得,很不方便

這個問題之前就有人發現了
現在做個紀錄~~

Document Timeline 結構:

Document Class:Main.as

package {
 import flash.display.*;
 import flash.events.*;
 
 public class Main extends MovieClip {
  public function Main():void{
   trace("Main(); start");
   gotoAndStop(2);
   trace(mc, getChildAt(0)); // null null
   gotoAndStop(1);
   gotoAndStop(2);
   trace(mc, getChildAt(0)); // null null
   trace("Main(); end");
   
   this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  }
  public function onEnterFrame(evtObj:Event):void{
   trace("onEnterFrame();");
   trace(mc, getChildAt(0)); // [object MovieClip] [object MovieClip]
   this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Output:

Main(); start
null null
null null
Main(); end
onEnterFrame();
[object MovieClip] [object MovieClip]

相關連結:
SWF10 時間軸預置物件行為的改變 Part 2
AS3 DisplayObject 四大變動屬性
SWF10 時間軸預置物件行為的改變
AS3 時間軸預置圖像物件的特性

Read more...

2007年9月26日 星期三

Flex 2 List 利用鍵盤作非連續性多選   [+/-]

Ticore's Blog

想要在 List 作多重選擇沒有什麼特別
但是要做到光靠鍵盤作非連續性的多重選擇可就難了
不光是實作上難,操作起來也有些複雜
Flash 內建的 List 沒有支援這功能
不過 Flex 2 ListBase 系列的 UIComponent 居然都有支援呢!

基本上,Flex 2 List 鍵盤非連續性的多重選擇操作方式與 Windows 相同
要先按住 [Ctrl] + [Alt],然後利用方向鍵瀏覽物件
用 [Space] 選擇或是取消
以下以實際圖片說明過程

首先執行 Flex List App

按下 [Tab] 鍵,Focus 到 List

按住 [Ctrl] + [Alt] 不放,進入選擇模式

繼續按住 [Ctrl] + [Alt] 不放,同時單擊 [Space] 選取第一個項目

繼續按住 [Ctrl] + [Alt] 不放,按三次 [Down],移動到第四個項目

繼續按住 [Ctrl] + [Alt] 不放,同時單擊 [Space] 選取第四個項目

放開 [Ctrl] + [Alt],這樣就完成鍵盤非連續性的多重選擇,選取第一、四個項目
之後便可以用 [Tab] 切換到其它 UIComponent 作其它動作

MXML Code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="horizontal" backgroundColor="#FFFFFF"
 height="200" width="200">
 <mx:List width="100" height="100%"
  allowMultipleSelection="true" textAlign="center" rowHeight="18">
  <mx:dataProvider>
   [0, 1 ,2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
  </mx:dataProvider>
 </mx:List>
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->
Read more...

Adobe 網站改版,改用 SWFObject   [+/-]

Ticore's Blog

最近發現 Adobe 網站大改版
也許畫面上改變沒那麼大
不過內部 CSS、JavaScript 卻是改了很多
變的比較簡潔 (建立離線瀏覽頁面簡單多了 ^_^)
網頁讀取速度似乎也變快了
最重要的是 Adobe 網站自己也捨棄 AC_RunActiveContent.js,改用 SWFObject

有圖有真相~~

除此之外,還用了好幾個其它非官方 JS Lib.

http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/Rel.js
http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/swfobject.js
http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/swfobject.addon.js
http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/remedy/button-value.js
http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/sIFR2.0.2/sifr.js
http://wwwimages.adobe.com/www.adobe.com/lib/com.adobe/sIFR2.0.2/sIFR-print.css
....

Read more...

2007年9月25日 星期二

AS3 時間軸預置圖像物件的特性   [+/-]

Ticore's Blog

時間軸預置圖像物件 (Timeline-Placed DisplayObject)
即是透過 Flash IDE 在時間軸預先放置好的 DisplayObject
與 AS3 動態加入的 DisplayObject 行為有些不太一樣
以下條列說明之

  1. Timeline-Placed DisplayObject 不能改變名稱,否則會出現 Error:
    Error: Error #2078: 無法修改 Timeline-placed 物件的名稱屬性。
    Error: Error #2078: The name property of a Timeline-placed object cannot be modified.

  2. 即使將 Timeline-Placed DisplayObject Reparenting,也不能改變其名稱。

  3. 以 AS3 將 Timeline-Placed DisplayObject Reparenting 之後,可以免於被 Timeline Remove。

  4. Timeline-Placed DisplayObject 被 Timeline Rmove 之後,
    該物件的 parent 屬性依然指向原本的 parent DisplayObjectContainer 物件,
    而且無法再被加入到任何 DisplayObjectContainer 之下 (Reparenting)。

  5. 被 Timeline Rmove 的 DisplayObject,所包含的 Child DisplayObject 仍可以做 Reparenting 動作。

相關連結:
SWF10 時間軸預置物件行為的改變 Part 2
AS3 DisplayObject 四大變動屬性
AS3 影格控制與時間軸預置物件的問題
SWF10 時間軸預置物件行為的改變

Read more...

2007年9月23日 星期日

新玩具 Cast Puzzle - Duet   [+/-]

Ticore's Blog

昨天逛台隆手創館的時候
突然在益智玩具區發現有趣東西
像是小時候玩過的金屬益智玩具 S&S、鹿角、....同系列產品
而且多了很多新樣式
都是日本進口的,看起來很精緻
每個售價大約是三百多
難度從等級一到等級六不等
像是鹿角屬於等級六的

而我最後選了難度五的『Cast Duet 磁』
結果在路上邊逛邊玩就解開了 ><"
感覺三百多白花了
其實後來發現想要原封不動裝回去反而更難呢

解開之前

解開之後

Cast Puzzle 網站

Read more...

2007年9月22日 星期六

Flex 2 各種有趣的邊框變化   [+/-]

Ticore's Blog

Flex 2 內的容器支援 Border 樣式設定
其中以 Solid Border 變化最多
可以做出圓角、半圓、......等有趣變化

Flex 2 Border Styles:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="#FFFFFF">
 <mx:Tile width="100%" height="100%" verticalGap="30" horizontalGap="30">
  <mx:Container width="50" height="50"
   cornerRadius="10" borderStyle="solid" borderThickness="6" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderSides="top left right" borderStyle="solid"
   borderThickness="6" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderSides="top left" borderStyle="solid" borderThickness="6" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderSides="top" borderStyle="solid" borderThickness="6" />
  <mx:Container width="50" height="40"
   cornerRadius="20" borderSides="top left right" borderStyle="solid"
   borderThickness="25" />
  <mx:Container width="50" height="50"
   cornerRadius="20" borderSides="top left" borderStyle="solid"
   borderThickness="25" />
  <mx:Container width="50" height="50"
   cornerRadius="50" borderSides="top left" borderStyle="solid"
   borderThickness="20" />
  <mx:Container width="50" height="50"
   cornerRadius="50" borderSides="top left" borderStyle="solid"
   borderThickness="50" />
  <mx:Container width="60" height="30"
   cornerRadius="30" borderSides="top left right" borderStyle="solid"
   borderThickness="30" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderSides="top left right" borderStyle="solid"
   borderThickness="10" backgroundColor="#808080" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderSides="left right" borderStyle="solid"
   borderThickness="10" backgroundColor="#808080" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderStyle="solid" borderThickness="40" />
  <mx:Container width="50" height="50"
   cornerRadius="10" borderStyle="solid" borderThickness="60" />
  <mx:Container width="50" height="50"
   cornerRadius="30" borderStyle="solid" borderThickness="60" />
  <mx:Container width="50" height="50"
   cornerRadius="1" borderStyle="solid" borderThickness="50" />
  <mx:Container width="50" height="50"
   cornerRadius="1" borderStyle="solid" borderThickness="60" />
  <mx:Container width="50" height="50"
   borderSides="top left" borderStyle="solid" borderThickness="60" />
  <mx:Container width="65" height="65"
   borderStyle="solid" borderThickness="55"  borderSides="top left right bottom"
   cornerRadius="12"/>
  <mx:Container width="80" height="80"
   borderStyle="solid" borderThickness="55"  borderSides="top left right bottom"
   cornerRadius="12" backgroundColor="#808080"/>
 </mx:Tile>
</mx:Application>
Read more...

2007年9月20日 星期四

Flex 2 技巧 - 圓角容器遮罩   [+/-]

Ticore's Blog

Flex 2 很多容器都有支援圓角邊框的設定 cornerRadius
不過容器的物件卻會超出圓角邊界
使用上不太方便~~

以下利用另一個圓角物件當作 Mask,遮住超出圓角的物件

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
 <mx:HBox>
  <mx:Label text="Border Thickness"/>
  <mx:NumericStepper id="step1" maximum="100" value="6"/>
  <mx:Label text="Corner Radius"/>
  <mx:NumericStepper id="step2" maximum="100" value="16"/>
 </mx:HBox>
 <mx:Canvas width="80%" height="80%" id="c1"
  borderStyle="solid" borderThickness="{step1.value}" cornerRadius="{step2.value}">
  <mx:Canvas width="100%" height="100%" id="c2"
   borderStyle="solid" borderThickness="0" cornerRadius="{step2.value - step1.value}"
   backgroundColor="#0" cacheAsBitmap="true"/>
  <mx:Canvas width="100%" height="100%" mask="{c2}" cacheAsBitmap="true">
   <mx:Button x="-32" y="-45" width="100" height="100" label="Button"/>
   <mx:Button x="228" y="-45" width="100" height="100" label="Button"/>
   <mx:Button x="390" y="119" width="100" height="100" label="Button"/>
   <mx:Button x="10" y="119" width="100" height="100" label="Button"/>
   <mx:Button x="218" y="263" width="100" height="100" label="Button"/>
   <mx:Button x="598" y="323" width="100" height="100" label="Button"/>
   <mx:Button x="598" y="-37" width="100" height="100" label="Button"/>
   <mx:Button x="-45" y="280" width="100" height="100" label="Button"/>
  </mx:Canvas>
 </mx:Canvas>
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->

執行效果:

Read more...

2007年9月8日 星期六

Flash Player MovieStar 與 NetStream.VideoCodec 代碼   [+/-]

Ticore's Blog

Flash Player MovieStar 開始支援 H.264、AAC 解碼
忽然想到 ActionScript 3.0 NetStream 有一些關於 Codec 的未公開屬性
以下就是用官方的那隻 mp4 影片測試得到的結果

videoCodec : 7, audioCodec : 10, decodedFrames : 1174

由於目前 Flash Player 9.0.60.184 沒有提供 Debug 版下載
所以只好克難點,把訊息直接打在畫面上
與之前的測試結果合起來~

videoCodec = 0:No Video Codec
videoCodec = 2:Sorenson Spark Codec
videoCodec = 4:On2 VP6 Codec
videoCodec = 7:H.264 Codec

至於 audioCodec 為什麼跳成 10 就搞不清楚了~

相關連結:
Flash Player 9 Update 支援 H.264
ActionScript 3.0 - NetStream 未公開的 Codec 函式

Read more...

AS3 技巧 - 快速取得 LoaderInfo.url   [+/-]

Ticore's Blog

在 ActionScript 3.0 已經無法像以前一樣
直接取用 _url 就可以得到本身 SWF 的 URL 位置
必須要從 DisplayObject.loaderInfo.url 獲得
對於一個非 DisplayObject 物件來說
要得到 url 實在很麻煩
要先取得一個 DisplayObject,還要確保該物件有 loaderInfo ......

以下介紹一個關於 LoaderInfo 的高級技巧
可以直接取得目前 SWF URL 位置
不管在什麼位置,不管是否可以取得 DisplayObject.loaderInfo
直接 new LoaderInfo,然後取得該物件 url 便是了

trace(new flash.display.LoaderInfo().url);

這是根據 LoaderInfo.url 變動性而來
以下配合實際例子示範:

Main Document Class:Main.as

package {
 import flash.display.*;
 import flash.net.*;
 import flash.events.*;
 import flash.system.*;

 public class Main extends MovieClip {
  
  public var app:ApplicationDomain = ApplicationDomain.currentDomain;
  
  public var ldr:Loader = new Loader();
  public var lcxt:LoaderContext = new LoaderContext(false, app);
  public var req:URLRequest = new URLRequest("Lib.swf");
  
  public function Main() {
   ldr.contentLoaderInfo.addEventListener(Event.INIT, onLibInit);
   ldr.load(req, lcxt);
  }
  
  public function onLibInit(evtObj:Event):void {
   var fun:* = app.getDefinition("Fun");
   trace(fun());
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Lib Document Class:Lib.as

package {
 import flash.display.*;
 
 public class Lib extends MovieClip {
  (Fun);
 }
}

Package Function:Fun.as

package {
 import flash.display.*;
 public function Fun():String {
  return new LoaderInfo().url;
 }
}

Lib.as 只是一個外殼,主要是將 Fun.as 編譯到 SWF 內

分別將 Main、Lib 編譯為 SWF 之後
執行 Main.swf,便會動態載入 Lib.swf
並呼叫定義在 Lib.swf 內的 Package Function - Fun
得到 Lib.swf URL

需要注意 new LoaderInfo() 動作無法在之後的 Flash Player 版本執行
Flash Player 9.0.64.0
Flash Player 9.0.60.120
Flash Player 9.0.60.184
Flash Player 9.0.60.235
Flash Player 9.0.115.0
Flash Player 9.0.124.0

Flash Player update 3 之後可以改用新方法 LoaderInfo.getLoaderInfoByDefinition 取得

相關連結:
AS3 DisplayObject 四大變動屬性
AS3 詭譎多變的 LoaderInfo (1)
AS3 詭譎多變的 LoaderInfo (2)

Read more...

AS3 詭譎多變的 LoaderInfo (2)   [+/-]

Ticore's Blog

在前一篇介紹了 LoaderInfo 固定性與變動性
接下來再進一步考慮比較複雜的情況

假如 MC3 Class 繼承 MC2 Class,MC2 Class 又繼承 MC1 Class
而這三個 Class 定義分別來自三個不同的 SWF
對於一個 MC3 Instance 呼叫定義在 MC1、MC2、MC3 Function 測試 LoaderInfo.url 會有什麼結果?

Lib1 Document Class:

package {
 import flash.display.*;
 public class Lib1 extends MovieClip {
  (MC1);
 }
}

MC1 Class:

package {
 import flash.display.*;
 public class MC1 extends MovieClip {
  
  public function showURL():void {
   trace("MC1.loaderInfo();");
   trace(" url:" + loaderInfo.url);
   trace(" loaderURL:" + loaderInfo.loaderURL);
   trace(" width:" + loaderInfo.width);
  }
 }
}

Lib2 Document Class:

package {
 import flash.display.*;
 public class Lib2 extends MovieClip {
  (MC2);
 }
}

MC2 Class:

package {
 import flash.display.*;
 public class MC2 extends MC1 {
  
  public override function showURL():void {
   super.showURL();
   trace("MC2.loaderInfo();");
   trace(" url:" + loaderInfo.url);
   trace(" loaderURL:" + loaderInfo.loaderURL);
   trace(" width:" + loaderInfo.width);
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Lib3 Document Class:

package {
 import flash.display.*;
 public class Lib3 extends MovieClip {
  (MC3);
 }
}

MC3 Class:

package {
 import flash.display.*;
 public class MC3 extends MC2 {
  
  public override function showURL():void {
   super.showURL();
   trace("MC3.loaderInfo();");
   trace(" url:" + loaderInfo.url);
   trace(" loaderURL:" + loaderInfo.loaderURL);
   trace(" width:" + loaderInfo.width);
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Main Document Class:

package {
 import flash.display.*;
 import flash.net.*;
 import flash.events.*;
 import flash.system.*;
 import flash.utils.*;

 public class Main extends MovieClip {
  
  var app:ApplicationDomain;

  var ldr1:Loader;
  var ldr2:Loader;
  var ldr3:Loader;
  
  var req1:URLRequest;
  var req2:URLRequest;
  var req3:URLRequest;
  
  var lcxt1:LoaderContext;
  var lcxt2:LoaderContext;
  var lcxt3:LoaderContext;
  
  public function Main() {
   
   init();
   loadLib1();

  }
  
  public function init() {
   
   app = ApplicationDomain.currentDomain;
   
   ldr1 = new Loader();
   ldr2 = new Loader();
   ldr3 = new Loader();
   
   req1 = new URLRequest("Lib1.swf");
   req2 = new URLRequest("Lib2.swf");
   req3 = new URLRequest("Lib3.swf");
   
   lcxt1 = new LoaderContext(false, app);
   lcxt2 = new LoaderContext(false, app);
   lcxt3 = new LoaderContext(false, app);
   
   ldr1.contentLoaderInfo.addEventListener(Event.INIT, onLib1Init);
   ldr2.contentLoaderInfo.addEventListener(Event.INIT, onLib2Init);
   ldr3.contentLoaderInfo.addEventListener(Event.INIT, onLib3Init);
   
  }
  public function loadLib1() {
   trace("loadLib1();");
   ldr1.load(req1, lcxt1);
   stop();
  }
  
  public function loadLib2() {
   trace("loadLib2();");
   ldr2.load(req2 ,lcxt2);
   stop();
  }
  
  public function loadLib3() {
   trace("loadLib3();");
   ldr3.load(req3 ,lcxt3);
   stop();
  }
  
  public function onLib1Init(evtObj:Event):void {
   trace("onLib1Init();");
   loadLib2();
  }
  
  public function onLib2Init(evtObj:Event):void {
   trace("onLib2Init();");
   loadLib3();
  }
  
  public function onLib3Init(evtObj:Event):void {
   trace("onLib3Init();");
   
   var mcClass:* = app.getDefinition("MC3");
   var mcIns:* = new mcClass();
   this.addChild(mcIns);
   mcIns.showURL();
   
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

以上 Lib 1~3 都是用來承載 MC 1~3 Class
需要注意最好將 Libs 分別放在不同的 Folder
Lib1 輸出 SWC 加入 Lib2 Classpath
Lib2 輸出 SWC 加入 Lib3 Classpath
避免 Class 重複編譯

執行 Main.swf 可以得到輸出結果

loadLib1();
onLib1Init();
loadLib2();
onLib2Init();
loadLib3();
onLib3Init();
MC1.loaderInfo();
 url:file:///C|/......../Lib1.swf
 loaderURL:file:///C|/......../Lib1.swf
 width:400
MC2.loaderInfo();
 url:file:///C|/......../Lib2.swf
 loaderURL:file:///C|/......../Lib2.swf
 width:400
MC3.loaderInfo();
 url:file:///C|/......../Lib3.swf
 loaderURL:file:///C|/......../Lib3.swf
 width:400

由輸出結果可以發現,對於同一個 MC3 Instance 而言
呼叫 Super Class 方法測試自身同一個 LoaderInfo 物件
得到結果是依據 Class Definition 位置而變

相關連結:
AS3 DisplayObject 四大變動屬性
AS3 詭譎多變的 LoaderInfo (1)
AS3 技巧 - 快速取得 LoaderInfo.url

Read more...

AS3 詭譎多變的 LoaderInfo (1)   [+/-]

Ticore's Blog

之前已經在 AS3 DisplayObject 四大變動屬性
介紹過 DisplayObject.loaderInfo 變動性
不過 LoaderInfo 詭異特性可不祇這樣而已~

依據 LoaderInfo 本身變動性,還可以分為「固定的 LoaderInfo」與「不固定的 LoaderInfo」兩種

所謂固定的 LoaderInfo,指對於同一個 LoaderInfo 實體而言
LoaderInfo.url 屬性不會變動
反之,不固定的 LoaderInfo,LoaderInfo.url 屬性則會隨著 caller 位置變動

一般情況下取得 LoaderInfo 大多是不固定的
而透過 Loader.contentLoaderInfo 也就是 Loader.content.loaderInfo 取得的
則是固定的 LoaderInfo

說到這,可能讓一些人非常震驚
因為文件上並沒有提到這特性
結果都當作一般物件行為處裡

以下做個簡單的測試

Main Document Class:Main.as

package {
 import flash.display.*;
 import flash.net.*;
 import flash.events.*;
 import flash.system.*;

 public class Main extends MovieClip {
  
  public var app:ApplicationDomain = ApplicationDomain.currentDomain;
  
  public var ldr:Loader = new Loader();
  public var lcxt:LoaderContext = new LoaderContext(false, app);
  public var req:URLRequest = new URLRequest("Lib.swf");
  
  public function Main() {
   this.addChild(ldr);
   ldr.contentLoaderInfo.addEventListener(Event.INIT, onLibInit);
   ldr.load(req, lcxt);
  }
  
  public function onLibInit(evtObj:Event):void {
   
   ldr.content["test"]("Lib Test Main.loaderInfo", root.loaderInfo);
   // Lib Test Main.loaderInfo
   // url : file:///C|/........../Lib.swf
   // loaderURL : file:///C|/........../Lib.swf
   
   var ldrInfo:LoaderInfo = new LoaderInfo();
   
   test("Main Test Main.new loaderInfo", ldrInfo);
   // Main Test Main.new loaderInfo
   // url : file:///C|/........../Main.swf
   // loaderURL : file:///C|/........../Main.swf
   
   ldr.content["test"]("Lib Test Main.new loaderInfo", ldrInfo);
   // Lib Test Main.new loaderInfo
   // url : file:///C|/........../Lib.swf
   // loaderURL : file:///C|/........../Lib.swf
   
  }
  
  public function test (msg:String, ldrInfo:LoaderInfo):void {
   trace(msg);
   trace("url : " + ldrInfo.url);
   trace("loaderURL : " + ldrInfo.loaderURL);
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Lib Document Class:Lib.as

package {
 import flash.display.*;
 import flash.events.Event;
 
 public class Lib extends MovieClip {
  
  public function Lib () {
   this.addEventListener(Event.ADDED_TO_STAGE, onAddStage);
  }
  
  public function onAddStage (evtObj:Event):void {
   
   parent.parent["test"]("Main Test Lib.loaderInfo", loaderInfo);
   // url : file:///C|/........../Lib.swf
   // loaderURL : ffile:///C|/........../Main.swf
   
  }
  
  public function test (msg:String, ldrInfo:LoaderInfo):void {
   trace(msg);
   trace("url : " + ldrInfo.url);
   trace("loaderURL : " + ldrInfo.loaderURL);
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

需要注意 new LoaderInfo() 動作無法在新的 Flash Player Beta 版執行
Flash Player 9.0.60.120
Flash Player 9.0.60.184
Flash Player 9.0.115.0
Flash Player 9.0.124.0

相關連結:
AS3 DisplayObject 四大變動屬性
AS3 詭譎多變的 LoaderInfo (2)
AS3 技巧 - 快速取得 LoaderInfo.url

Read more...

2007年9月4日 星期二

AS3 valueOf 的妙用   [+/-]

Ticore's Blog

最近在使用 ActionScript 3.0 Proxy 類別時
忽然發現 valueOf 非常方便
使用 Proxy 層層嵌套物件之後,需要作脫殼動作時
valueOf 就可以派上用場
一般情況下,幾乎不用額外撰寫程式碼
以下是簡單的例子~

Main Class:

package {
 import flash.display.*;
 
 public class Main extends MovieClip {
  
  public function Main () {
   
   var obj:Object = {name: "Object 01"};
   var sehll1:Shell = new Shell(obj);
   var sehll2:Shell = new Shell(sehll1);
   trace(sehll2.name); // Object 01
   trace(sehll2.valueOf().valueOf() == obj); // true
   
  }
  
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

Shell Class:

package {
 import flash.utils.*;
 
 public dynamic class Shell extends Proxy {
  
  private var obj:Object;
  
  public function Shell (obj:Object) {
   this.obj = obj;
  }
  
  flash_proxy override function callProperty(name:*, ...rest):* {
   return obj[name].apply(obj, rest);
  }
  
  flash_proxy override function deleteProperty(name:*):Boolean {
   return delete obj[name];
  }
  
  flash_proxy override function getProperty(name:*):* {
   return obj[name];
  }
  
  flash_proxy override function setProperty(name:*, value:*):void {
   obj[name] = value;
  }
  
 }
}
// Ticore's Blog - http://ticore.blogspot.com/
Read more...

AS3 MouseEvent.relatedObject   [+/-]

Ticore's Blog

ActionScript 3.0 的 MouseEvent 與 FocusEvent 增加了好用的屬性 - relatedObject
可以直接在處理該事件同時獲得前後相對應的物件
類似的功能想要在 AS 2.0 上實做,就要花不少功夫了~

把之前的程式 AS3 - MouseOver 與 RollOver 差異性 (3) 加上 relatedObject 資料輸出
可以得到以下輸出結果

eventPhase : 1, currentTarget : null, target : MC1, type : rollOver
eventPhase : 1, currentTarget : root1, target : MC1, type : rollOver
eventPhase : 2, currentTarget : MC1, target : MC1, type : rollOver
eventPhase : 1, currentTarget : null, target : root1, type : rollOver
eventPhase : 2, currentTarget : root1, target : root1, type : rollOver

eventPhase : 1, currentTarget : null, target : MC1, type : mouseOver
eventPhase : 1, currentTarget : root1, target : MC1, type : mouseOver
eventPhase : 2, currentTarget : MC1, target : MC1, type : mouseOver
eventPhase : 3, currentTarget : root1, target : MC1, type : mouseOver
eventPhase : 3, currentTarget : null, target : MC1, type : mouseOver

eventPhase : 1, currentTarget : null, target : MC1, type : mouseOut, relatedObject : MC2
eventPhase : 1, currentTarget : root1, target : MC1, type : mouseOut, relatedObject : MC2
eventPhase : 2, currentTarget : MC1, target : MC1, type : mouseOut, relatedObject : MC2
eventPhase : 3, currentTarget : root1, target : MC1, type : mouseOut, relatedObject : MC2
eventPhase : 3, currentTarget : null, target : MC1, type : mouseOut, relatedObject : MC2

eventPhase : 1, currentTarget : null, target : MC2, type : rollOver, relatedObject : MC1
eventPhase : 1, currentTarget : root1, target : MC2, type : rollOver, relatedObject : MC1
eventPhase : 1, currentTarget : MC1, target : MC2, type : rollOver, relatedObject : MC1
eventPhase : 2, currentTarget : MC2, target : MC2, type : rollOver, relatedObject : MC1

eventPhase : 1, currentTarget : null, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 1, currentTarget : root1, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 1, currentTarget : MC1, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 2, currentTarget : MC2, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 3, currentTarget : MC1, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 3, currentTarget : root1, target : MC2, type : mouseOver, relatedObject : MC1
eventPhase : 3, currentTarget : null, target : MC2, type : mouseOver, relatedObject : MC1

eventPhase : 1, currentTarget : null, target : MC2, type : mouseOut
eventPhase : 1, currentTarget : root1, target : MC2, type : mouseOut
eventPhase : 1, currentTarget : MC1, target : MC2, type : mouseOut
eventPhase : 2, currentTarget : MC2, target : MC2, type : mouseOut
eventPhase : 3, currentTarget : MC1, target : MC2, type : mouseOut
eventPhase : 3, currentTarget : root1, target : MC2, type : mouseOut
eventPhase : 3, currentTarget : null, target : MC2, type : mouseOut

eventPhase : 1, currentTarget : null, target : root1, type : rollOut
eventPhase : 2, currentTarget : root1, target : root1, type : rollOut
eventPhase : 1, currentTarget : null, target : MC1, type : rollOut
eventPhase : 1, currentTarget : root1, target : MC1, type : rollOut
eventPhase : 2, currentTarget : MC1, target : MC1, type : rollOut
eventPhase : 1, currentTarget : null, target : MC2, type : rollOut
eventPhase : 1, currentTarget : root1, target : MC2, type : rollOut
eventPhase : 1, currentTarget : MC1, target : MC2, type : rollOut
eventPhase : 2, currentTarget : MC2, target : MC2, type : rollOut

Mouse Event relatedObject 1

Mouse Event relatedObject 2

相關連結:
MouseEvent.relatedObject
FocusEvent.relatedObject

Read more...

2007年9月1日 星期六

Flex 2 Drag and Drop 練習   [+/-]

Ticore's Blog

以下是 Flex 2 Drag & Drop 練習
可以在 Canvas 容器內拖拉放物件
也可以跨 Canvas 容器拖放物件

Flex 2 Cross Canvas Drag & Drop

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   creationComplete="init();" layout="horizontal" >
 <mx:Script>
  <![CDATA[
   import mx.core.*;
   import mx.containers.*;
   import mx.managers.*;
   import mx.events.*;
   
   [SWF(frameRate=30)]
   
   public function init():*{
    
    genSqr();
    
    cont1.addEventListener(DragEvent.DRAG_ENTER, onDragEnter);
    cont2.addEventListener(DragEvent.DRAG_ENTER, onDragEnter);
    
    cont1.addEventListener(DragEvent.DRAG_DROP, onDragDrop);
    cont2.addEventListener(DragEvent.DRAG_DROP, onDragDrop);
    
   }
   
   public function genSqr():*{
    var sqr:Canvas;
    for (var i:Number = 0 ; i < 10 ; ++i) {
     sqr = new Canvas();
     sqr.setStyle("backgroundColor", Math.random() * 0xFFFFFF);
     sqr.x = Math.random() * 150;
     sqr.y = Math.random() * 150;
     sqr.width = 50;
     sqr.height = 50;
     sqr.addEventListener(MouseEvent.MOUSE_MOVE, doDrag);
     sqr.addEventListener(DragEvent.DRAG_COMPLETE, onDragComplete);
     cont1.addChild(sqr);
    }
   }
   
   public function doDrag(evtObj:MouseEvent):void{
    
    if (!evtObj.buttonDown) {
     return;
    }
    
    var dragInitiator:Canvas = Canvas(evtObj.currentTarget);
    var ds:DragSource = new DragSource();
    ds.addData(dragInitiator, "item");
    ds.addData(evtObj.localX, "offsetX");
    ds.addData(evtObj.localY, "offsetY");
    
    var canvasProxy:Canvas = new Canvas();
    canvasProxy.width = 50;
    canvasProxy.height = 50;
    canvasProxy.setStyle("backgroundColor", dragInitiator.getStyle("backgroundColor"));
    DragManager.doDrag(dragInitiator, ds, evtObj, canvasProxy);
    
   }
   
   public function onDragEnter(evtObj:DragEvent):void{
    
    var dropTarget:Canvas = Canvas(evtObj.currentTarget);
    
    if (evtObj.dragSource.hasFormat("item")) {
     DragManager.acceptDragDrop(dropTarget);
    }
    
   }
   
   public function onDragDrop(evtObj:DragEvent):void{
    var dropTarget:Canvas = Canvas(evtObj.currentTarget);
    var dropItem:Canvas = Canvas(evtObj.dragSource.dataForFormat("item"));
    
    dropItem.x = evtObj.localX - Number(evtObj.dragSource.dataForFormat("offsetX"));
    dropItem.y = evtObj.localY - Number(evtObj.dragSource.dataForFormat("offsetY"));
    
    dropItem.parent.removeChild(dropItem);
    dropTarget.addChild(dropItem);
   }
   
   public function onDragComplete(evtObj:DragEvent):void{
    //trace(evtObj.target);
   }
   
  ]]>
 </mx:Script>
 <mx:Canvas id="cont1" width="200" height="200" backgroundColor="0xFFFFFF">
 </mx:Canvas>
 <mx:Spacer width="50" />
 <mx:Canvas id="cont2" width="200" height="200" backgroundColor="0xFFFFFF">
 </mx:Canvas>
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->

線上範例 Demo:

Read more...