乍看之下有點像 processing
同樣是 Java Base
不過 F3 是一種直譯式的 Java scripting language
對於 Swing、Java 2D 支援度良好
適合用來開發 UI
F3 語法規則
The F3 Programming Language
F3 的作者已經用 F3 作了幾個 Demo
幾乎可以做到等同 Flash 網站的效果
更多的 Demo 請到 F3 觀看

現已更名為 JavaFX Read more...
Flash、Flex、AIR、ActionScript 相關研究心得

張貼者: {id: "Ticore"}; // 位於 11/30/2006 12:57:00 上午 0 意見 此文章的連結
標籤: Java, NEWS, RIA, Technology
以往 Flash Communication Server 執行的 Server-Side ActionScript
完全是以原始碼來執行
原始碼容易外洩,而且檔案一多,部署也比較麻煩
Flash Media Server 內附一個好用的工具
位於 FMS 安裝目錄下
C:\Program Files\Macromedia\Flash Media Server 2\tools\far.exe
可以將你的 SSAS 程式碼編譯為 bytecode,以及打包壓縮為 *.far
除了保護原始碼、容易部署以外
文件上說還可以加快 application 啟動速度
以下示範利用 Ant 來編譯打包一個 FMS Application
<?xml version="1.0" encoding="UTF-8"?>
<project name="FMS SSAS" default="package">
<property name="src" location="src" />
<property name="build" location="build" />
<property name="dist" location="dist" />
<property name="far"
location="C:\Program Files\Macromedia\Flash Media Server 2\tools\far.exe" />
<fileset id="ascFiles" dir="${build}">
<include name="**/*.asc" />
</fileset>
<target name="init">
<tstamp />
<mkdir dir="${build}" />
<mkdir dir="${dist}" />
</target>
<target name="copy" depends="init">
<copy todir="${build}">
<fileset dir="${src}/" />
</copy>
</target>
<target name="compile" depends="copy">
<apply executable="${far}" dir="${build}">
<arg value="-compile" />
<fileset refid="ascFiles" />
</apply>
<delete>
<fileset dir="${build}" includes="**/*.asc" />
</delete>
</target>
<target name="package" depends="compile">
<exec executable="${far}" dir="${build}">
<arg value="-package" />
<arg value="-archive" />
<arg value="${dist}\main.far" />
<arg value="-files" />
<arg value="*.ase" />
<arg value="components\*.ase" />
</exec>
</target>
</project>
相關資料:
FMS LiveDocs - Archiving and compiling server-side script files
Read more...張貼者: {id: "Ticore"}; // 位於 11/29/2006 12:40:00 下午 0 意見 此文章的連結
標籤: ActionScript, Ant, AS1, Flash-Media-Server
Flash 8 (含)以前 的場景 (Scene) 全部都是模擬出來的
純粹只是為了開發上方便
不用一次處理超長時間軸
實際輸出的 SWF 資料內是完全沒有任何關於場景的資料!
舉例來說,像是 gotoAndStop("Scene 2", 3); 函式呼叫
編譯之後都會被轉成類似 gotoAndStop(6); 這樣的格式
想要在 Flash 8 以前作判斷目前場景的功能
需要自己另外用陣列或是物件去儲存場景資料
相當麻煩
至於影格標籤 (Frame Label) 雖然在執行期可以使用,但是支援度很差
無法列舉標籤,也無法直接取得目前影格上的標籤
不過 Flash 9 & ActionScript 3 已經加強對 Scene & FrameLabel 的處理能力
可以直接做到上述的功能
以下是測試程式
先照圖所示用 Flash 9 IDE 建立場景與影格標籤:
在影格一輸入測試程式:
// 列舉所有 Scene、Frame Label
for each(var scene:Scene in this.scenes) {
trace(scene.name + ", numFrames = " + scene.numFrames );
for each(var label:FrameLabel in scene.labels) {
trace("t" + label.name + ", frame = " + label.frame);
}
}
// 偵測目前播放位置的 Scene、Frame Label、Frame Number
this.addEventListener(Event.ENTER_FRAME,
function(event:Event):void{
var mc:MovieClip = event.target;
trace("Current Frame : " + mc.currentFrame,
", Current Label : " + mc.currentLabel,
", Current Scene : " + mc.currentScene.name);
}
);
輸出範例:
Scene 1, numFrames = 19 label 1, frame = 4 label 2, frame = 10 label 3, frame = 16 Scene 2, numFrames = 17 label 4, frame = 1 label 5, frame = 6 label 6, frame = 11 Current Frame : 2 , Current Label : null , Current Scene : Scene 1 Current Frame : 3 , Current Label : null , Current Scene : Scene 1 Current Frame : 4 , Current Label : label 1 , Current Scene : Scene 1 Current Frame : 5 , Current Label : null , Current Scene : Scene 1 Current Frame : 6 , Current Label : null , Current Scene : Scene 1 Current Frame : 7 , Current Label : null , Current Scene : Scene 1 Current Frame : 8 , Current Label : null , Current Scene : Scene 1 Current Frame : 9 , Current Label : null , Current Scene : Scene 1 Current Frame : 10 , Current Label : label 2 , Current Scene : Scene 1 Current Frame : 11 , Current Label : null , Current Scene : Scene 1 Current Frame : 12 , Current Label : null , Current Scene : Scene 1 Current Frame : 13 , Current Label : null , Current Scene : Scene 1 Current Frame : 14 , Current Label : null , Current Scene : Scene 1 Current Frame : 15 , Current Label : null , Current Scene : Scene 1 Current Frame : 16 , Current Label : label 3 , Current Scene : Scene 1 Current Frame : 17 , Current Label : null , Current Scene : Scene 1 Current Frame : 18 , Current Label : null , Current Scene : Scene 1 Current Frame : 19 , Current Label : null , Current Scene : Scene 1 Current Frame : 1 , Current Label : label 4 , Current Scene : Scene 2 Current Frame : 2 , Current Label : null , Current Scene : Scene 2 Current Frame : 3 , Current Label : null , Current Scene : Scene 2 Current Frame : 4 , Current Label : null , Current Scene : Scene 2 Current Frame : 5 , Current Label : null , Current Scene : Scene 2 Current Frame : 6 , Current Label : label 5 , Current Scene : Scene 2 Current Frame : 7 , Current Label : null , Current Scene : Scene 2 Current Frame : 8 , Current Label : null , Current Scene : Scene 2 Current Frame : 9 , Current Label : null , Current Scene : Scene 2 Current Frame : 10 , Current Label : null , Current Scene : Scene 2 Current Frame : 11 , Current Label : label 6 , Current Scene : Scene 2 Current Frame : 12 , Current Label : null , Current Scene : Scene 2 Current Frame : 13 , Current Label : null , Current Scene : Scene 2 Current Frame : 14 , Current Label : null , Current Scene : Scene 2 Current Frame : 15 , Current Label : null , Current Scene : Scene 2 Current Frame : 16 , Current Label : null , Current Scene : Scene 2 Current Frame : 17 , Current Label : null , Current Scene : Scene 2Read more...
張貼者: {id: "Ticore"}; // 位於 11/28/2006 10:40:00 上午 0 意見 此文章的連結
標籤: ActionScript, AS3, Flash, FrameLabel
AS 3.0 中 flash.net.NetStream 內有三個未公開的函式
分別是
[Inspectable(environment="none")] public function get videoCodec():uint; [Inspectable(environment="none")] public function get audioCodec():uint; [Inspectable(environment="none")] public function get decodedFrames():uint;
你也可以自行使用
trace(flash.utils.describeType(flash.net.NetStream));
看到這些函式
顧名思義,應該是取得 Video、Audio Codec 種類,以及已經解壓縮的影格數
以下是測試程式
Flash 9 Frame 1 AS:
import flash.net.*;
import flash.event.*;
import flash.utils.*;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.client = {};
ns.client.onMetaData = function(infoObj:Object):void{
for(var i:String in infoObj) {
trace("infoObj['" + i + "'] : " + infoObj[i]);
}
};
ns.client.onCuePoint = function(info:Object):void{};
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
function(event:Event) {
trace("event : " + event);
event.target.close();
}
);
ns.play("flashVideo.flv");
var video:Video = new Video();
video.attachNetStream(ns);
this.addChild(video);
var timer:Timer = new Timer(500, 10);
timer.addEventListener(TimerEvent.TIMER,
function(event:Event):void{
trace("videoCodec : " + ns.videoCodec, ", audioCodec : " +
ns.audioCodec, ", decodedFrames : " + ns.decodedFrames);
}
);
timer.start();
輸出範例:
infoObj['audiocodecid'] : 2 infoObj['videocodecid'] : 4 infoObj['canSeekToEnd'] : true infoObj['width'] : 413 infoObj['audiodelay'] : 0.038 infoObj['duration'] : 60.326 infoObj['framerate'] : 29.969985961914063 infoObj['height'] : 162 infoObj['videodatarate'] : 450 infoObj['audiodatarate'] : 96 videoCodec : 4 , audioCodec : 2 , decodedFrames : 11 videoCodec : 4 , audioCodec : 2 , decodedFrames : 26 videoCodec : 4 , audioCodec : 2 , decodedFrames : 41 videoCodec : 4 , audioCodec : 2 , decodedFrames : 56 videoCodec : 4 , audioCodec : 2 , decodedFrames : 71 videoCodec : 4 , audioCodec : 2 , decodedFrames : 86 videoCodec : 4 , audioCodec : 2 , decodedFrames : 101 videoCodec : 4 , audioCodec : 2 , decodedFrames : 116 videoCodec : 4 , audioCodec : 2 , decodedFrames : 132 videoCodec : 4 , audioCodec : 2 , decodedFrames : 147
分別用來播放 On2 VP6、Sorenson Spark Codec Flash Video
可以發現
videoCodec = 0:No Video Codec
videoCodec = 2:Sorenson Spark Codec
videoCodec = 4:On2 VP6 Codec
至於 audioCodec 只有出現 0、2,2 應該就是 mp3 了
相同的功能也可以從 onMetaData 事件 info 物件中取得
infoObj['audiocodecid'] : 2
infoObj['videocodecid'] : 4
未來也許可能會支援其它的 Codec 也說不定
相關連結:
Flash Player 9 Update 支援 H.264
Flash Player MovieStar 與 NetStream.VideoCodec 代碼
張貼者: {id: "Ticore"}; // 位於 11/27/2006 08:22:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Codec, NetConnection, NetStream, Undocumented
ActionScript 3.0 的 DisplayObject 泛指所有在畫面上呈現圖像的物件
Shape、MorphShape、Video、Bitmap 等,都是 DisplayObject
而 DisplayObjectContainer 便是可以容納其它 DisplayObject 的容器
MovieClip、Sprite、Stage 等,都是 DisplayObjectContainer
DisplayObject 繼承圖:
DisplayObjectContainer 與 AS 2 的 MovieClip 類似
具有 parent、child 的階層關係,以及疊加的特性
不過關於深度的操作上更加方便
感覺上有點像是在操作一個會自動縮併的陣列
只要移除掉陣列內某一位置的元素
該陣列便會自動縮短
這樣一來,只要在合法的索引範圍內取用 child
永遠不會取到 null
也不用像 AS 2 的列舉方式,還要自己判定物件型別
※列舉 DisplayObjectContainer 內的 DisplayObject
var container:DisplayObjectContainer = this;
for(var i:Number = 0 ; i < container.numChildren ; ++i) {
trace(container.getChildAt(i));
}
※交換 DisplayObject 深度
※自 DisplayObjectContainer 內移除 DisplayObject
※將子 DisplayObject 重新加入 DisplayObjectContainer
※將 DisplayObject 插入 DisplayObjectContainer
Read more...
張貼者: {id: "Ticore"}; // 位於 11/26/2006 07:00:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, DisplayObject, Flash, MovieClip, Reparenting
2007/06/17 更新
Jesse Warden 提出利用 _global 共通的特性
用一個個 SWF8 版本的 Proxy.swf 集中控制
Jesse Warden dot Kizz-om - Controlling Flash Player 8 SWFs in Flash Player 9 SWFs
Jesse Warden dot Kizz-om - Flex Controlling Flash
張貼者: {id: "Ticore"}; // 位於 11/25/2006 10:38:00 上午 0 意見 此文章的連結
張貼者: {id: "Ticore"}; // 位於 11/23/2006 09:03:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Flash, Undocumented
AS 3.0 還有許多未公開的函式
以下是關於 MovieClip 的新功能
MovieClip.addFrameScript(frame:uint,notify:Function)
FlashGuru Consulting - Undocumented Actionscript 3
可以對指定的影格加上事件
與 EventDispatcher 不太一樣的是
它只能容納一個 listener
後加入的會把之前的取代
function output():void {
trace(this + " : " + this.currentFrame);
}
var i:Boolean = true;
addFrameScript(10, output);
// 影格要拉到 11 格以上
FlashGuru 指出停止事件的方式為
addFrameScript(10, output, false, false);
可是我測試都是失敗
發現以下的方式可以成功移除事件
addFrameScript(10, null);
2006/11/23 補充
senocular 在該文回應
其實 addFrameScript 是接受不定長度的 影格數目與 function 組合
e.g.
function output():void {
trace(this + " : " + this.currentFrame);
}
addFrameScript(0, output, 1, output, 2, output);
這樣就可以一次設定多個影格事件
Read more...張貼者: {id: "Ticore"}; // 位於 11/22/2006 04:48:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Flash, Frame-Script, Undocumented
這問題在之前的 ActionScript WeakReference 介紹中曾經有提過
當使用 Flash Player 9 執行 AS 2.0 程式
利用 LocalConnection 物件進行連線
該 LC 物件與其它物件形成隔絕狀態
將會造成 LC 物件無法被回收
FMS SSAS 程式不需要撰寫
只需要命名一個空白文字檔為 main.asc
部署於 nc_gc_app application 下即可
Flash ActionScript 測試程式:
function doTest():Void {
var nc:NetConnection = new NetConnection();
nc.connect("rtmp:/nc_gc_app");
var lc:LocalConnection = new LocalConnection();
lc.connect("lc" + Math.random());
lc.nc = nc;
nc.lc = lc;
delete lc;
delete nc;
}
setInterval(doTest, 200);
分別使用 Flash Player 8、9 就會發現
Flash Player 9 累積到 500 條連線都不會回收
Flash Player 8 則是每達到一定量
就會回收一次
以上的 Bug 直到 Flash Player 9.0.124.0 還是存在
Read more...張貼者: {id: "Ticore"}; // 位於 11/22/2006 10:48:00 上午 0 意見 此文章的連結
標籤: ActionScript, Bug, Flash-Player, GC, LocalConnection, NetConnection, Stream-Server
測試原理:
利用 NetConnection 與 FMS 連線
透過 FMS Console 觀察 NetConnection 活動數量
藉以測試函式範圍鏈內物件回收的情況
FMS 程式:
FMS SSAS 程式均不需要特別撰寫
只需要命名一個空的文字檔為 main.asc
部署在 nc_gc_app application 內
測試一:
var ary:Array = [];
function getFun():Function {
var nc:NetConnection = new NetConnection();
nc.connect("rtmp:/nc_gc_app");
return function ():Void {
};
}
function doTest():Void {
ary.push(getFun());
}
setInterval(doTest, 100);
// Ticore's Blog - http://ticore.blogspot.com/
測試二:
var ary:Array = [];
function getFun():Function {
var nc:NetConnection = new NetConnection();
nc.connect("rtmp:/nc_gc_app");
return function ():Void {
nc;
// 明確引用到範圍鏈內的物件,會造成物件無法回收
};
}
function doTest():Void {
ary.push(getFun());
}
setInterval(doTest, 100);
// Ticore's Blog - http://ticore.blogspot.com/
測試三:
var ary:Array = [];
function getFun():Function {
var nc:NetConnection = new NetConnection();
nc.connect("rtmp:/nc_gc_app");
return function ():Void {
eval("");
// 只要有 eval 出現,Scope Chain 內的物件都會被 hold 住
};
}
function doTest():Void {
ary.push(getFun());
}
setInterval(doTest, 100);
// Ticore's Blog - http://ticore.blogspot.com/
測試程式大略以 Flash Player 6 ~ 9 測試
在此不直接 PO 出結果了,有興趣的話可以自行測試看看
從結果中可以發現
1.在匿名函式中,明確引用到範圍鏈內的物件時,會造成該物件無法被回收。
(其它在範圍鏈內沒有被明確引用到的物件是可以被回收的)
2.在匿名函式中,使用到 eval 時,即使沒有明確引用到任何範圍鏈內的物件,也會造成範圍鏈內的物件無法被回收
其實 Flash Player 可能並沒有像 Scope Chain and Memory waste in Flash MX 一文中所述,會造成大量記憶體浪費。
也有可能是前 Macromedia 後來改善了~~
要視明確引用的物件數量多寡,以及是否使用到 eval 而定
碰巧該文假定 eval 對 GC 沒有影響,利用 eval 來作測試
以上假如有誤,請指正,謝謝~
相關參考資料:
Scope Chain and Memory waste in Flash MX
Flash MX 中的範圍鏈 (scope chain)與記憶體浪費
ActionScript Weak Reference 介紹
AS 3.0 利用function scope 暫存變數
AS 2.0 將參數與 function 綁在一起
張貼者: {id: "Ticore"}; // 位於 11/21/2006 03:30:00 下午 0 意見 此文章的連結
標籤: ActionScript, GC, NetConnection, Scope-Chain
由於 ActionScript 3.0 語法變得相當嚴謹
事件處理上也是
不像以前 AS 2.0 隨便 new 一個物件都可以當作事件 (Event) 發佈出去
flash.events.Event 本身不是一個 dynamic class
也沒有一般性的資料欄位可供使用
想要在自訂事件裡面傳遞一些額外資料變得比較困難
必須要自行繼承 Event
以下示範如何自訂一個事件
Read more...
張貼者: {id: "Ticore"}; // 位於 11/20/2006 05:49:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Event-Listener
程式碼:
function doFun(arg:Number):Void {
trace("doFun : " + arg);
}
function createFun(arg):Function {
return function () {
doFun(arg);
};
}
btn1.onPress = createFun(1);
btn2.onPress = createFun(2);
相關參考資料:張貼者: {id: "Ticore"}; // 位於 11/20/2006 02:28:00 下午 0 意見 此文章的連結
Flex 2、ActionScript 3.0 出來到現在
其實還有很多功能文件上並沒有列出來
像是 flash.debugger.enterDebugger
這對於 Flex 2 開發人員非常方便
比設立中斷點的方式更具有彈性
可以由程式的直接結果動態決定是否要進入除錯模式
Read more...
張貼者: {id: "Ticore"}; // 位於 11/16/2006 05:02:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Debug, Flex
拜 Adobe 捐出 AVM 原始碼給 Mozilla 基金會所賜
已經有人作出簡單的 AS3 反編譯程式
A first decompilor AS3
不過目前並不能完整還原程式碼
只能得到中間語言 (intermediate language)
AS3 Decompiler 下載位置
以下是簡單的輸出結果:
另外 Mozilla Tamarin 下面還有 AS3 的直譯器在開發中
有興趣的人可以下來玩玩看
張貼者: {id: "Ticore"}; // 位於 11/16/2006 01:07:00 下午 0 意見 此文章的連結
標籤: ActionScript, AS3, Decompile, Tools
看到邦邦的問題,測試出來的結果如下:
SWF URL:
http://riafiles.googlepages.com/gradientMask.swf
PNG URL:
http://riafiles.googlepages.com/gradientMask.png
關鍵應該是在設定 mask.cacheAsBitmap 的時機
ActionScript:
var maskURL:String = maskURL == null ? "gradientMask.png" : maskURL;
import flash.geom.*;
var maskee:MovieClip = this.createEmptyMovieClip("maskee", 100);
var masker:MovieClip = this.createEmptyMovieClip("masker", 200);
with (maskee) {
colors = [0xFF0000, 0x0000FF];
fillType = "radial"
alphas = [100, 100];
ratios = [0, 0xFF];
spreadMethod = "reflect";
interpolationMethod = "linearRGB";
focalPointRatio = 0.9;
matrix = new Matrix();
matrix.createGradientBox(100, 100, Math.PI, 0, 0);
beginGradientFill(fillType, colors, alphas, ratios, matrix,
spreadMethod, interpolationMethod, focalPointRatio);
moveTo(0, 0);
lineTo(550, 0);
lineTo(550, 200);
lineTo(0, 200);
lineTo(0, 0);
endFill();
}
var mcLoader:MovieClipLoader = new MovieClipLoader();
var mcLisObj:Object = {};
mcLisObj.onLoadInit = function(evtObj):Void{
masker.cacheAsBitmap = true;
masker.onPress = function():Void{
startDrag(this);
};
masker.onRelease = masker.onReleaseOutside = function():Void{
stopDrag();
};
maskee.cacheAsBitmap = true;
maskee.setMask(masker);
};
mcLoader.addListener(mcLisObj);
mcLoader.loadClip(maskURL, masker);
// Ticore's Blog - http://ticore.blogspot.com/
Read more...
張貼者: {id: "Ticore"}; // 位於 11/09/2006 01:42:00 下午 0 意見 此文章的連結
標籤: ActionScript, BitmapData, Flash, Graphics, Mask