Flash CS3 Export Motion XML Kevin Hoyt
Motion XML || XML Motion scripts for Flash CS3
2007-06-29
2007-06-28
取得 FLV 內的 header 資料
依據 osFlash 裡 FLV 檔案資料格式的說明, 利用 Flash 開發「取得 FLV 檔頭資料及串流資料」的 AIR app。
要注意的是 meta 裡包含兩個 AMF packets, 所以需使用 ByteArray.readObject() 兩次。
Flash frame AS3:
FLV 的第一個 stream unit 應該都是 meta。較舊 FLV 的 meta 大多有問題, 沒有提供仔細而實用的資料。
較新格式的 FLV 其 Flags 通常是 13 而不是 5。
原始檔: parseFLV.fla
安裝檔: parseFLV.air
要注意的是 meta 裡包含兩個 AMF packets, 所以需使用 ByteArray.readObject() 兩次。
Flash frame AS3:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
var file:File;
var fs:FileStream;
var flvFilter:FileFilter = new FileFilter("Flash Video", "*.flv");
var header_ba:ByteArray;
var stream_ba:ByteArray;
function bClick(e:MouseEvent):void {
var targetName:String = e.target.name;
switch (targetName) {
case "open_btn" :
file = new File();
file.browseForOpen("Open", [flvFilter]);
file.addEventListener(Event.SELECT, readFLVHeader);
break;
case "show_btn" :
readStreamHeader();
break;
case "close_btn" :
fs.close();
break;
}
}
open_btn.addEventListener(MouseEvent.CLICK, bClick);
show_btn.addEventListener(MouseEvent.CLICK, bClick);
close_btn.addEventListener(MouseEvent.CLICK, bClick);
function readFLVHeader(e:Event) {
filename_txt.text = file.nativePath;
fs = new FileStream();
fs.open(file, FileMode.READ);
// read FLV Header
header_ba = new ByteArray();
fs.readBytes(header_ba, 0, 9);
main_txt.text = "Signature: "+ header_ba.readMultiByte(3, "") +"\n";
main_txt.appendText("Version: "+ header_ba.readUnsignedByte()+"\n");
main_txt.appendText("Flags: "+ header_ba.readUnsignedByte()+"\n");
main_txt.appendText("Offset: "+ header_ba.readUnsignedInt()+"\n");
main_txt.appendText("---\n");
}
function readStreamHeader() {
stream_ba = new ByteArray();
fs.readBytes(stream_ba, 0, 15);
main_txt.appendText("PreviousTagSize: "+ stream_ba.readInt()+" ----\n");
var type:uint = stream_ba.readUnsignedByte();
main_txt.appendText("Type: "+ type +"\n");
// 取 3 bytes
var bodyLength:uint = stream_ba.readUnsignedShort()<<8 | stream_ba.readUnsignedByte();
main_txt.appendText("BodyLength: "+ bodyLength +"\n");
var timestamp:uint = stream_ba.readUnsignedShort()<<8 | stream_ba.readUnsignedByte();
main_txt.appendText("Timestamp: "+ timestamp +"\n");
main_txt.appendText("Padding: "+ stream_ba.readUnsignedInt()+"\n");
if (type == 0x12) {
var t_ba:ByteArray = new ByteArray();
fs.readBytes(t_ba, 0, bodyLength);
// 設定 AMF 的格式, 即使是 on2 VP6 應該還是舊的
t_ba.objectEncoding = ObjectEncoding.AMF0;
// 第一個 AMF 物件是事件處理器的資料
var obj:Object = t_ba.readObject();
var str:String = QopDump.go( obj );
main_txt.appendText("***\nEvent handler:"+str+"\n***\n");
obj = t_ba.readObject();
str = QopDump.go( obj );
main_txt.appendText(str+"\n");
} else {
// skip the body
fs.position += bodyLength;
}
main_txt.verticalScrollPosition = main_txt.maxVerticalScrollPosition;
}
FLV 的第一個 stream unit 應該都是 meta。較舊 FLV 的 meta 大多有問題, 沒有提供仔細而實用的資料。
較新格式的 FLV 其 Flags 通常是 13 而不是 5。
原始檔: parseFLV.fla
安裝檔: parseFLV.air
2007-06-27
利用 NativeDragEvent, 以拖拉放的方式開啟檔案
參考網頁: Simple Drag and Drop AIR
依據上一篇: Adobe AIR Simple Text Editor 再加上拖曳開檔的功能
Flash frame actions:
原始檔: test_dragAndDrop.fla
依據上一篇: Adobe AIR Simple Text Editor 再加上拖曳開檔的功能
Flash frame actions:
import flash.events.NativeDragEvent;
import flash.desktop.DragManager;
import flash.desktop.DragActions;
import flash.desktop.TransferableFormats;
import flash.desktop.TransferableData;
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER,onDragIn);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP,onDrop);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT,onDragExit);
function onDragIn(event:NativeDragEvent):void {
// acceptDragDrop() 只能在 nativeDragEnter 或 nativeDragOver 事件處理器上使用
DragManager.acceptDragDrop(this);
}
function onDrop(event:NativeDragEvent):void {
// 下行若沒設定, 順序會是 copy, move, link
DragManager.dropAction = DragActions.COPY;
var tfd:TransferableData = event.transferable as TransferableData;
var dropfiles:Array = tfd.dataForFormat(TransferableFormats.FILE_LIST_FORMAT) as Array;
// 只取一個檔案
var sourceFile:File = dropfiles[0];
file = new File();
file.nativePath = sourceFile.nativePath;
filename_txt.text = file.nativePath;
fs = new FileStream();
fs.open(file, FileMode.READ);
var str:String = fs.readMultiByte(fs.bytesAvailable, "utf-8");
main_txt.text = str.replace( new RegExp(File.lineEnding, "g"), "\n");
fs.close();
}
function onDragExit(event:NativeDragEvent):void {
trace("Drag exit event.");
}
原始檔: test_dragAndDrop.fla
2007-06-26
Adobe AIR Simple Text Editor
這個例子主要是用來測試 File.browseForOpen 的功能
缺點還很多, 包含只能讀寫 utf-8 編碼的檔案
Flash frame actions:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
var file:File;
var fs:FileStream;
var textFilter:FileFilter = new FileFilter("Text", "*.txt");
file = new File("app-resource:/temp.txt");
filename_txt.text = file.nativePath;
function bClick(e:MouseEvent):void {
var targetName:String = e.target.name;
switch (targetName) {
case "new_btn" :
file = new File("app-resource:/temp.txt");
filename_txt.text = file.nativePath;
main_txt.text = "";
break;
case "load_btn" :
file = new File();
file.browseForOpen("Open", [textFilter]);
file.addEventListener(Event.SELECT, onSelectOpenFile);
break;
case "save_btn" :
fs = new FileStream();
fs.open(file, FileMode.WRITE);
fs.writeMultiByte(main_txt.text, "utf-8");
fs.close();
break;
case "saveas_btn" :
file = new File();
file.browseForSave("Save as");
file.addEventListener(Event.SELECT, onSelectWriteFile);
break;
}
}
new_btn.addEventListener(MouseEvent.CLICK, bClick);
load_btn.addEventListener(MouseEvent.CLICK, bClick);
save_btn.addEventListener(MouseEvent.CLICK, bClick);
saveas_btn.addEventListener(MouseEvent.CLICK, bClick);
function onSelectOpenFile(e:Event) {
filename_txt.text = file.nativePath;
fs = new FileStream();
fs.open(file, FileMode.READ);
var str:String = fs.readMultiByte(fs.bytesAvailable, "utf-8");
// 替換 換行符號
main_txt.text = str.replace( new RegExp(File.lineEnding, "g"), "\n");
fs.close();
file.removeEventListener(Event.SELECT, onSelectOpenFile);
}
function onSelectWriteFile(e:Event) {
filename_txt.text = file.nativePath;
fs = new FileStream();
fs.open(file, FileMode.WRITE);
fs.writeMultiByte(main_txt.text, "utf-8");
fs.close();
file.removeEventListener(Event.SELECT, onSelectWriteFile);
}
原始檔: test_browseForOpen.fla
2007-06-25
2007-06-23
AIR local database 測試
Flash frame AS3:
執行第一次的結果 (由無到有建立DB):
執行第二次的結果 (取得資料秀在 DataGrid 上):
import flash.data.SQLResult;
import flash.filesystem.File;
import flash.data.SQLStatement;
import flash.data.SQLConnection;
import flash.events.SQLEvent;
import flash.events.SQLErrorEvent;
import flash.errors.SQLError;
import fl.data.DataProvider;
var dbFile:File = new File("app-resource:/test01.db");
var dbConn:SQLConnection = new SQLConnection();
var dbStatement:SQLStatement;
var insertCount:uint = 0;
dbConn.addEventListener(SQLEvent.OPEN, onDBOpened);
dbConn.addEventListener(SQLErrorEvent.ERROR, onDBError);
// 若檔案不存在, 會自動建立
dbConn.open(dbFile);
function onDBOpened(e:SQLEvent) {
trace("onDBOpened:", e);
if (e.type == SQLEvent.OPEN) {
dbStatement = new SQLStatement();
dbStatement.sqlConnection = dbConn;
dbStatement.text = "select * from Users";
dbStatement.addEventListener(SQLEvent.RESULT, onSQLResult);
dbStatement.addEventListener(SQLErrorEvent.ERROR, onSQLError);
dbStatement.execute();
}
}
function onDBError(e:SQLErrorEvent) {
trace("onDBError:", e);
}
function onSQLResult(e:SQLEvent) {
trace("onSQLResult:", e);
var d:Array = dbStatement.getResult().data;
QopDump.echo(d);
dataGrid.dataProvider = new DataProvider(d);
dbConn.close();
}
function onSQLError(e:SQLErrorEvent) {
trace("onSQLError:", e);
var err:SQLError = e.error;
trace("Error Code:", err.code);
trace("Operation:", err.operation);
trace("Error Message:", err.message, "\n");
if (err.message.indexOf("no such table") != -1) {
dbStatement = new SQLStatement();
dbStatement.sqlConnection = dbConn;
dbStatement.text = "CREATE TABLE Users "+
"(id INTEGER PRIMARY KEY, username TEXT, password TEXT);";
dbStatement.addEventListener(SQLEvent.RESULT, doInsert);
dbStatement.addEventListener(SQLErrorEvent.ERROR, onSQLError);
dbStatement.execute();
}
}
function doInsert(e:SQLEvent) {
insertCount++;
if(insertCount>3) return;
dbStatement = new SQLStatement();
dbStatement.sqlConnection = dbConn;
var sql:String;
switch (insertCount) {
case 1 :
sql = "INSERT INTO Users VALUES(null,'MyName','MyPassword');";
break;
case 2 :
sql = "INSERT INTO Users VALUES(null,'qop','qop543');";
break;
case 3 :
sql = "INSERT INTO Users VALUES(null,'小黑','出運了');";
break;
}
dbStatement.text = sql;
dbStatement.addEventListener(SQLEvent.RESULT, doInsert);
dbStatement.execute();
}
執行第一次的結果 (由無到有建立DB):
執行第二次的結果 (取得資料秀在 DataGrid 上):
AIR local database
AIR 內含 SQLite SQL database engine
每個資料庫都以一個檔案實體存在
官網: SQLite home page
工具: SQLite Database Browser, SQLite Control Center
每個資料庫都以一個檔案實體存在
官網: SQLite home page
工具: SQLite Database Browser, SQLite Control Center
2007-06-22
AIR 存圖測試
Flash Frame Actions:
原始檔: saveImgFile.fla (as3corelib 已經包含在原始檔內)
import com.adobe.images.JPGEncoder;
import com.adobe.images.PNGEncoder;
import flash.filesystem.*;
jpg_btn.addEventListener(MouseEvent.CLICK, saveImg);
png_btn.addEventListener(MouseEvent.CLICK, saveImg);
function saveImg(e:MouseEvent):void {
var tname = e.target.name;
var file:File = File.applicationResourceDirectory;
var bpd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
var ba:ByteArray;
bpd.draw(root);
if(tname == "jpg_btn"){
var jpg:JPGEncoder = new JPGEncoder(80);
ba = jpg.encode(bpd);
file = file.resolve("test.jpg");
}else if(tname == "png_btn"){
ba = PNGEncoder.encode(bpd);
file = file.resolve("test.png");
}
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(ba);
fileStream.close();
}
原始檔: saveImgFile.fla (as3corelib 已經包含在原始檔內)
2007-06-21
as3corelib
as3corelib: ActionScript 3.0 library for several basic utilities.
裡面的工具都很有用, 包含常用的 JPGEncoder, JSON, MD5, PNGEncoder, SHA1.
在 Flash IDE 使用, 大多使用類別原始碼, 也可以使用 SWC. 以下是使用 SWC 的方式
1. 把 corelib.swc 放在 Flash CS3 安裝目錄的 en\Configuration\Components.
2. 開啟 Flash CS3.
3. 在 components 面板裡可以看到「standard components」>「DateFormatter」.
4. 把「DateFormatter」放在文件的元件庫即可.
裡面的工具都很有用, 包含常用的 JPGEncoder, JSON, MD5, PNGEncoder, SHA1.
在 Flash IDE 使用, 大多使用類別原始碼, 也可以使用 SWC. 以下是使用 SWC 的方式
1. 把 corelib.swc 放在 Flash CS3 安裝目錄的 en\Configuration\Components.
2. 開啟 Flash CS3.
3. 在 components 面板裡可以看到「standard components」>「DateFormatter」.
4. 把「DateFormatter」放在文件的元件庫即可.
2007-06-20
package a flash app as an AIR file (for windows)
請參考 Create AIR Apps in Flash CS3 在 Flash CS3 中安裝 Test in Apollo
下載並解開 package_app_as_an_AIR_file.zip
然後將修改後的檔案蓋過
在 Flash CS3 開啟文件, 再點選「Commands」>「package app as an AIR file」即可
查看一下是否有 .air 生成
當然也可以用手動的方式, 參考 adt 的使用
下載並解開 package_app_as_an_AIR_file.zip
然後將修改後的檔案蓋過
在 Flash CS3 開啟文件, 再點選「Commands」>「package app as an AIR file」即可
查看一下是否有 .air 生成
當然也可以用手動的方式, 參考 adt 的使用
AIR 存檔測試
Flash Frame Actions:
原始檔: saveTextFile.fla
import flash.filesystem.*;
// var file:File = File.documentsDirectory; // 我的文件
var file:File = File.applicationResourceDirectory; // 應用程式所在的目錄
file = file.resolve("test.txt");
trace(file.nativePath); // 於 DOS 視窗輸出
function doSave(e:MouseEvent):void {
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.UPDATE);
// File.systemCharset 為系統編碼
//fileStream.writeMultiByte(_txt.text, File.systemCharset);
fileStream.writeMultiByte(_txt.text, "utf-8");
fileStream.close();
}
function doLoad(e:MouseEvent):void {
var fileStream:FileStream = new FileStream();
try{
fileStream.open(file, FileMode.READ);
//_txt.text = fileStream.readMultiByte(file.size, File.systemCharset);
_txt.text = fileStream.readMultiByte(file.size, "utf-8");
}catch(err:IOError){
_txt.text = "No data!";
}
fileStream.close();
sbar.update();
}
function doClear(e:MouseEvent):void {
_txt.text = "";
sbar.update();
}
save_btn.addEventListener(MouseEvent.CLICK, doSave);
load_btn.addEventListener(MouseEvent.CLICK, doLoad);
clear_btn.addEventListener(MouseEvent.CLICK, doClear);
原始檔: saveTextFile.fla
2007-06-19
Create AIR Apps in Flash CS3
AIR SDK 請安裝新的 beta
參考 Create Apollo Apps in Flash CS3 安裝「Test in Apollo.mxp」
如果之前已經安裝 apollo alpha1 sdk
1. 直接將「C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Test in Apollo\config.dat」的內容改成新 SDK 的路徑, 例如:
2. 將「C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Test in Apollo\apollo-app-template.xml」的內容改成:
如果從未安裝「Test in Apollo.mxp」, 安裝之後, 如上述第2點修改 apollo-app-template.xml 即可。
漏掉了一件事, playerglobal.swc 也要更新。
參考 Create Apollo Apps in Flash CS3 安裝「Test in Apollo.mxp」
如果之前已經安裝 apollo alpha1 sdk
1. 直接將「C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Test in Apollo\config.dat」的內容改成新 SDK 的路徑, 例如:
file:///C|/air_b1_win_sdk_061107
2. 將「C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Test in Apollo\apollo-app-template.xml」的內容改成:
<application xmlns="http://ns.adobe.com/air/application/1.0.M4" appId="$appId" version="$version">
<name>$name</name>
<title>$name</title>
<publisher>$publisher</publisher>
<description>$description</description>
<copyright>$copyright</copyright>
<rootContent systemChrome="standard" visible="true">[the name of your main file will be put here]</rootContent>
</application>
如果從未安裝「Test in Apollo.mxp」, 安裝之後, 如上述第2點修改 apollo-app-template.xml 即可。
漏掉了一件事, playerglobal.swc 也要更新。
- Download Flex 3 SDK 3 beta 1 and unzip it
- Copy the airglobal.swc from the frameworks\libs\air folder of the Flex 3 SDK 3 beta 1
- Paste it into the \en\Configuration\ActionScript 3.0\Classes folder of your Adobe Flash CS3 installation
- Delete the playerglobal.swc file that is inside of that same folder
- Rename the airglobal.swc file to playerglobal.swc
Adobe Extension mxi 於 Windows 存放的路徑
路徑在:
C:\Documents and Settings\USERID\Application Data\Adobe\Extension Manager\Configuration\Extensions
以 Flash CS3 為例, mxi 中指的 $flash 為:
C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration
C:\Documents and Settings\USERID\Application Data\Adobe\Extension Manager\Configuration\Extensions
以 Flash CS3 為例, mxi 中指的 $flash 為:
C:\Documents and Settings\USERID\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration
2007-06-18
元件會自動轉換為類別
沒有設定連結的元件, 和設定連結的元件類似, 可能會被轉換為類別
如果元件內沒有 frame actions, 元件實體會屬於 MovieClip 類型
如果元件內包含 frame actions, 則轉換為「元件名_X」的類別, 其中 X 為 z-order index
參考原始檔: symbol_to_class.fla
既然為類別, 元件內定義的 functions (不論在哪一影格定義), 在實體出現時即可被呼叫
當然也可以由類別建立物件
參考原始檔: symbol_to_class_2.fla
如果元件內沒有 frame actions, 元件實體會屬於 MovieClip 類型
如果元件內包含 frame actions, 則轉換為「元件名_X」的類別, 其中 X 為 z-order index
參考原始檔: symbol_to_class.fla
既然為類別, 元件內定義的 functions (不論在哪一影格定義), 在實體出現時即可被呼叫
當然也可以由類別建立物件
參考原始檔: symbol_to_class_2.fla
Z-order Index (part 2)
移除 DisplayObject 時, 其原本所佔用的 index, 會被後面的物件所遞補
參考 設定連結的元件會變成類別 原始檔
Frame actions :
點按1號物件後的輸出結果:
若欲取得某 DisplayObject 的所有子物件, 可以搭配使用:
參考 設定連結的元件會變成類別 原始檔
Frame actions :
var ar:Array = new Array();
var s:Symbol1;
for (var i:int=0; i<6; i++) {
s = new Symbol1();
s.x = s.width*i;
s.y = 100;
s._txt.text = String(i+1);
s.name = 's'+(i+1);
s.addEventListener(MouseEvent.CLICK, cOnClick);
this.addChild(s);
ar.push(s);
}
function cOnClick(e:MouseEvent):void {
var t_mc:MovieClip = e.currentTarget as MovieClip;
t_mc.parent.removeChild(t_mc);
trace('子物件數目:', this.numChildren);
for (var i:int=0; i < ar.length; i++) {
if (this.contains(ar[i])) {
trace(ar[i].name, ':', this.getChildIndex(ar[i]) );
}
}
}
點按1號物件後的輸出結果:
子物件數目: 5
s2 : 0
s3 : 1
s4 : 2
s5 : 3
s6 : 4
若欲取得某 DisplayObject 的所有子物件, 可以搭配使用:
for(var k:int=0; k < this.numChildren; k++){
var d:DisplayObject = this.getChildAt(k);
trace(d.name);
}
Z-order Index (part 1)
在 AS2, 稱為 depth; 在 AS3, 稱 z-order index
有兩個方法可以改變 z-order index:
兩者的參數必須是合法的 DisplayObject (已存在的子物件)
或者合法的 index (已存在子物件的索引)
因此, 所有已被使用的 indexes 必定是連號的
(例如: 0,1,2,3,4,5,6)
不會有中間空號沒被使用的情形
(不會發生: 0,1,2, 4,5,6,7)
有兩個方法可以改變 z-order index:
swapChildren(child1:DisplayObject, child2:DisplayObject):void
swapChildrenAt(index1:int, index2:int):void
兩者的參數必須是合法的 DisplayObject (已存在的子物件)
或者合法的 index (已存在子物件的索引)
因此, 所有已被使用的 indexes 必定是連號的
(例如: 0,1,2,3,4,5,6)
不會有中間空號沒被使用的情形
(不會發生: 0,1,2, 4,5,6,7)
2007-06-16
Loading External module-SWF
參考 ActionScript 3 Tip of the Day: Loading External Classes with ApplicationDomain
載入模組測試
load_module_loadee01.fla 包含 linkaged symbol: Symbol1
load_module_loader01.fla
原始檔: load_module_01.zip
載入模組測試
load_module_loadee01.fla 包含 linkaged symbol: Symbol1
load_module_loader01.fla
var my_this = this;
var ldr:Loader = new Loader();
var ldrContext:LoaderContext = new LoaderContext();
// 使用 loader 的類別域
ldrContext.applicationDomain = ApplicationDomain.currentDomain;
ldr.load(new URLRequest("load_module_loadee01.swf"), ldrContext);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
function onComplete(e:Event):void{
/*
var Symbol1:Class =
ApplicationDomain.currentDomain.getDefinition('Symbol1')
as Class;
*/
var Symbol1:Class = getDefinitionByName('Symbol1')
as Class;
var s:MovieClip = new Symbol1();
this.addChild(s);
}
原始檔: load_module_01.zip
2007-06-15
載入 SWF 後的物件關係 (AS3)
loadee.fla :
loader.fla :
loadee.fla 裡內有一個 MovieClip「a_mc」
loader.fla 裡內有一個 MovieClip「b_mc」
執行 loader.swf 後, 再按 b_mc 後的結果:
由結果可知 :
1. loader root -> ldr -> loadee root -> a_mc
(上式 -> 表示包含子物件)
2. 每個 swf 裡的 root 參照是固定的, 不因被載入而改變
a_mc.alpha = 0.5;
trace('a_mc.parent:',
a_mc.parent, "::",
a_mc.parent.name);
trace('a_mc.parent.parent:',
a_mc.parent.parent, "::",
a_mc.parent.parent.name);
trace('a_mc.parent.parent.parent:',
a_mc.parent.parent.parent, "::",
a_mc.parent.parent.parent.name);
trace('a_mc.parent==root :', a_mc.parent==root);
trace('------------');
loader.fla :
var my_this = this;
var ldr:Loader = new Loader();
ldr.load(new URLRequest("loadee.swf"));
addChild(ldr);
b_mc.addEventListener(MouseEvent.CLICK, function():void{
trace(ldr.content.name);
ldr.content['a_mc'].rotation = 30;
});
loadee.fla 裡內有一個 MovieClip「a_mc」
loader.fla 裡內有一個 MovieClip「b_mc」
執行 loader.swf 後, 再按 b_mc 後的結果:
a_mc.parent: [object MainTimeline] :: instance4
a_mc.parent.parent: [object Loader] :: instance3
a_mc.parent.parent.parent: [object MainTimeline] :: root1
a_mc.parent==root : true
------------
instance4
由結果可知 :
1. loader root -> ldr -> loadee root -> a_mc
(上式 -> 表示包含子物件)
2. 每個 swf 裡的 root 參照是固定的, 不因被載入而改變
由物件取得類別名
由物件取得類別名, 使用 getQualifiedClassName()
由物件取得類別資料, 使用 describeType()
由類別名取得類別物件, 使用 getDefinitionByName()
例:
由物件取得類別資料, 使用 describeType()
由類別名取得類別物件, 使用 getDefinitionByName()
例:
var sprite:Sprite = new Sprite();
// 取得物件的類別資訊
trace(getQualifiedClassName(sprite));
// 取得物件所屬類別的父類別資訊
trace(getQualifiedSuperclassName(sprite));
// 由字串取得類別
var c:Class = getDefinitionByName("flash.display::Sprite") as Class;
var s:Sprite = new c();
trace(getQualifiedClassName(s));
trace(getQualifiedSuperclassName(s));
AS3 FlashVars
Flash AS3 用
Flex 2 用
在 HTML/JavaScript 中修改
順帶一提, Flash 檔名請符合變數命名規則, 也應避免使用 _ (underscore)
root.loaderInfo.parameters // 或 stage.loaderInfo.parameters
Flex 2 用
Application.application.parameters
在 HTML/JavaScript 中修改
if (AC_FL_RunContent == 0) {
alert("This page requires AC_RunActiveContent.js.");
} else {
AC_FL_RunContent(
'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
'width', '550',
'height', '400',
'src', 'flashvars_test',
'quality', 'high',
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
'align', 'middle',
'play', 'true',
'loop', 'true',
'scale', 'showall',
'wmode', 'window',
'devicefont', 'false',
'id', 'flashvars_test',
'bgcolor', '#ffffff',
'name', 'flashvars_test',
'menu', 'false',
'allowFullScreen', 'false',
'allowScriptAccess','sameDomain',
'movie', 'flashvars_test',
'flashvars', 'a=777', // shinder added
'salign', ''
); //end AC code
}
順帶一提, Flash 檔名請符合變數命名規則, 也應避免使用 _ (underscore)
設定連結的元件會變成類別
設定元件的連結
若無定義類別, Flash 會自動幫你產生一個
在這個例子裡, Symbol1 裡有一個動態文字物件 _txt
AS3 已經沒有 attachMovie() 可用
複製 MovieClip 時,使用 new 和 addChild
結果:
原始檔
若無定義類別, Flash 會自動幫你產生一個
在這個例子裡, Symbol1 裡有一個動態文字物件 _txt
AS3 已經沒有 attachMovie() 可用
複製 MovieClip 時,使用 new 和 addChild
var s:Symbol1;
for (var i:int=0; i<6; i++) {
s = new Symbol1();
s.x = s.width*i;
s.y = s.height/2*i;
s._txt.text = String(i+1);
addChild(s);
}
結果:
原始檔
2007-06-14
AS3 Event Phases
ActionScript 3 的事件物件傳遞方式
Adobe ActionScript Article: Introduction to event handling in ActionScript 3.0
Event Object 由外傳至內(capture phase), 達到標的物件(target phase)後, 再往外傳(bubbling phase)
addEventListener() 的第三個參數 (useCapture) 就是用來決定,
偵聽器是否在 capture phase 時偵聽事件並觸發
useCapture 預設值為 false, 因此事件在 target phase 或 bubbling phase 可以被偵聽。
以下是個說明的例子:
用滑鼠擊點 m2 後的結果:
Adobe ActionScript Article: Introduction to event handling in ActionScript 3.0
Event Object 由外傳至內(capture phase), 達到標的物件(target phase)後, 再往外傳(bubbling phase)
addEventListener() 的第三個參數 (useCapture) 就是用來決定,
偵聽器是否在 capture phase 時偵聽事件並觸發
useCapture 預設值為 false, 因此事件在 target phase 或 bubbling phase 可以被偵聽。
以下是個說明的例子:
var m1:MovieClip = new MovieClip();
m1.graphics.beginFill(0xFF9900);
m1.graphics.drawRect(100, 100, 200, 200);
m1.graphics.endFill();
m1.name = 'm1';
var m2:MovieClip = new MovieClip();
m2.graphics.beginFill(0x99FF00);
m2.graphics.drawRect(140, 140, 120, 120);
m2.graphics.endFill();
m2.name = 'm2';
addChild(m1);
m1.addChild(m2);
function mHandler(e:MouseEvent) {
switch (e.eventPhase) {
case EventPhase.CAPTURING_PHASE :
trace('capture');
break;
case EventPhase.AT_TARGET :
trace('at target');
break;
case EventPhase.BUBBLING_PHASE :
trace('bubbling');
}
trace('currentTarget: ' +e.currentTarget.name + e.currentTarget);
trace('target: ' + e.target.name + '\n');
}
stage.addEventListener(MouseEvent.CLICK, mHandler);
root.addEventListener(MouseEvent.CLICK, mHandler);
m1.addEventListener(MouseEvent.CLICK, mHandler);
m1.addEventListener(MouseEvent.CLICK, mHandler); // 重複註冊偵聽器
m2.addEventListener(MouseEvent.CLICK, mHandler);
stage.addEventListener(MouseEvent.CLICK, mHandler, true);
root.addEventListener(MouseEvent.CLICK, mHandler, true);
m1.addEventListener(MouseEvent.CLICK, mHandler, true);
m2.addEventListener(MouseEvent.CLICK, mHandler, true); // 這一行沒有作用
用滑鼠擊點 m2 後的結果:
capture
currentTarget: null[object Stage]
target: m2
capture
currentTarget: root1[object MainTimeline]
target: m2
capture
currentTarget: m1[object MovieClip]
target: m2
at target
currentTarget: m2[object MovieClip]
target: m2
bubbling
currentTarget: m1[object MovieClip]
target: m2
bubbling
currentTarget: root1[object MainTimeline]
target: m2
bubbling
currentTarget: null[object Stage]
target: m2
2007-06-13
由 URL 取得 Domain Name (AS2 版)
在測試和發佈 Flash Remoting 專案時還滿有用的
原始檔 MyDomain.as
原始檔 MyDomain.as
/**
* author: shinder lin
* email: shinder.lin@gmail.com
*/
class MyDomain {
static var defaultDomain = "http://localhost";
static function getDomain() {
var url_str = _root._url;
if (url_str.indexOf("http://") == 0) {
var s_index = url_str.indexOf("/", 10);
return url_str.substring(0, s_index);
} else {
return defaultDomain;
}
}
}
SDDump - Dump 的 AS2 版
原始檔 SDDump.as
/**
* author: shinder lin
* email: shinder.lin@gmail.com
*/
class SDDump {
static var n:Number = 0;
static var str:String = '';
static function echo(a) {
trace(go(a));
}
static function go(a) {
str = '';
dumpIt(a);
str = str.slice(0, str.length-1);
return str;
}
static function dumpIt(a) {
if (a instanceof Array) {
dumpArray(a);
} else if (a instanceof Object) {
dumpObject(a);
} else {
appendStr(a);
}
}
static function dumpArray(ar:Array):Void {
n++;
for (var o in ar) {
if (ar[o] instanceof Object) {
appendStr("["+o+"]:");
dumpIt(ar[o]);
} else {
appendStr("["+o+"]:"+ar[o]);
}
}
n--;
}
static function dumpObject(obj:Object):Void {
n++;
for (var o in obj) {
if (obj[o] instanceof Object) {
appendStr(o+":");
dumpIt(obj[o]);
} else {
appendStr(o+":"+obj[o]);
}
}
n--;
}
static function appendStr(s):Void {
str += getSpaces()+s+'\n';
}
static function getSpaces():String {
var s:String = '';
for (var i = 1; i < n; i++) {
s += " ";
}
return s;
}
}
2007-06-12
Adobe AIR beta
之前代號為 Apollo, 現在正式稱為 Adobe AIR
釋出 public beta Adobe Integrated Runtime (AIR)
相關新聞: Adobe推Apollo平台測試版 正名AIR
Flex 3 也 beta 了, 請看 Adobe Labs
釋出 public beta Adobe Integrated Runtime (AIR)
相關新聞: Adobe推Apollo平台測試版 正名AIR
Flex 3 也 beta 了, 請看 Adobe Labs
AS3 frame actions 可以定義 setter/getter functions
Flash CS3 AS3 的 frame actions 可以用 setter/getter 囉
雖然不能使用 private 宣告變數
但是可以定義 setter/getter functions 就很方便了
雖然不能使用 private 宣告變數
但是可以定義 setter/getter functions 就很方便了
var t:Number = 10;
function set test(n:Number):void {
t=n;
}
function get test():Number {
return t;
}
trace('t='+t);
test = 99;
trace('t='+t);
2007-06-11
The rules of frame actions converting to a class definition ?
承上一篇: Frame Action 的 Function literal 裡的 Scope
個人「純猜測」可能轉換成類別定義:
然而 frame1 應該不是 class member, 所以應該比較像這樣:
紅色字的部份應該是在 addFrameScript() 裡面運作
個人「純猜測」可能轉換成類別定義:
package {
import flash.display.MovieClip;
public class TestMC8 extends MovieClip {
public var me:Object = this;
public var o:Object = {};
public var i:Number = 6;
public function TestMC8() {
addFrameScript(0, frame1);
}
internal function frame1():void {
o.a = function():void{
this.c = function():void{
};
};
o.b = function():void{
trace(i);
trace(this.i);
trace(me.i);
};
o.a();
o.b();
}
}
}
然而 frame1 應該不是 class member, 所以應該比較像這樣:
package {
import flash.display.MovieClip;
public class TestMC8a extends MovieClip {
public var me:Object = this;
public var o:Object = {};
public var i:Number = 6;
public function TestMC8a() {
function frame1():void{
o.a = function():void{
this.c = function():void{
};
};
o.b = function():void{
trace(i);
trace(this.i);
trace(me.i);
};
o.a();
o.b();
trace(this);
}
addFrameScript(0, function(){
frame1.apply(me);
});
}
}
}
紅色字的部份應該是在 addFrameScript() 裡面運作
Frame Action 的 Function literal 裡的 Scope
之前在 mmug 的討論: Flash CS3 - AS3 又一影格程式問題
老方式用 describeType() 去檢查. 以 literal 方式定義的 function objects, 其內部的變數若不是以 this 為開頭, 皆會被轉換為 影格所在MovieClip 物件的屬性。
Frame Actions:
結果:
老方式用 describeType() 去檢查. 以 literal 方式定義的 function objects, 其內部的變數若不是以 this 為開頭, 皆會被轉換為 影格所在MovieClip 物件的屬性。
Frame Actions:
var me:Object = this;
var o:Object = {};
o.a = function():void{
var i:Number = 6;
this.c = function():void{
var k;
};
};
o.b = function():void{
trace(i);
trace(this.i);
trace(me.i);
};
o.a();
o.b();
trace(describeType(this));
結果:
6
undefined
6
...
<variable name="k" type="*"/>
<variable name="i" type="Number"/>
<variable name="me" type="Object"/>
<variable name="o" type="Object"/>
...
MainTimeline Frame Functions -> Class Methods
Flash CS3 裡 MainTimeline frame actions 定義的 functions (not literal)
如何轉換成 class methods 的定義呢 ?
測試了一下, 無論在哪一格定義, 全都變成 public class methods
Frame 1:
Frame 6:
輸出結果:
如何轉換成 class methods 的定義呢 ?
測試了一下, 無論在哪一格定義, 全都變成 public class methods
Frame 1:
b();
a();
function a():void {
trace('a');
}
Frame 6:
stop();
function b():void {
trace('b');
}
trace(describeType(this));
輸出結果:
b
a
<type name="Untitled_fla::MainTimeline" base="flash.display::MovieClip" isDynamic="true" isFinal="false" isStatic="false">
...
<method name="a" declaredBy="Untitled_fla::MainTimeline" returnType="void"/>
<method name="b" declaredBy="Untitled_fla::MainTimeline" returnType="void"/>
...
2007-06-10
AS3 未公開的類別和方法
網路上的資源:
Ticore's Blog: ActionScript 3.0 未公開的函式 AVM1Movie.call、addCallback, ActionScript 3.0 未公開的函式 MovieClip.addFrameScript
Experimenting with AS3 ,Apollo and HaXe: ActionScript3中未公开的一些方法和类
在 Flash CS3 開個 AS3 新文件, 輸入 Frame Actions
得到的結果, 可以找到
依照 metadata 標籤又可以找到
addFrameScript 和 AccessibilityImplementation 都是 undocumented.
Ticore's Blog: ActionScript 3.0 未公開的函式 AVM1Movie.call、addCallback, ActionScript 3.0 未公開的函式 MovieClip.addFrameScript
Experimenting with AS3 ,Apollo and HaXe: ActionScript3中未公开的一些方法和类
在 Flash CS3 開個 AS3 新文件, 輸入 Frame Actions
trace(describeType(this));
得到的結果, 可以找到
<method name="addFrameScript" declaredBy="flash.display::MovieClip" returnType="void">
<metadata name="Inspectable">
<arg key="environment" value="none"/>
</metadata>
</method>
依照 metadata 標籤又可以找到
<accessor name="accessibilityImplementation" access="readwrite" type="flash.accessibility::AccessibilityImplementation" declaredBy="flash.display::InteractiveObject">
<metadata name="Inspectable">
<arg key="environment" value="none"/>
</metadata>
</accessor>
addFrameScript 和 AccessibilityImplementation 都是 undocumented.
Colin Moock - actionscript 3.0 and flash cs3
Colin Moock - 演講大綱
actionscript 3.0 and flash cs3
explains how to integrate ActionScript 3.0 code with content created in the flash cs3 authoring tool.
actionscript 3.0 and flash cs3
explains how to integrate ActionScript 3.0 code with content created in the flash cs3 authoring tool.
AS3 與 AMFPHP 1.2 part 3 - Credentials
AS3 沒有 setCredentials() 了
而是利用 NetConnection.addHeader(), 下兩行是 Help 裡說明
Adds a context header to the AMF packet structure.
This header is sent with every future AMF packet.
Flash AS3:
而是利用 NetConnection.addHeader(), 下兩行是 Help 裡說明
Adds a context header to the AMF packet structure.
This header is sent with every future AMF packet.
Flash AS3:
var nc:NetConnection = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.connect('http://localhost/amfphp/gateway.php');
nc.addHeader("Credentials", false,
{userid:'kitty', password:'kitty'});
var responder:Responder = new Responder(onResult, onError);
nc.call('myremoting.DataOp_6.isLogin', responder);
function onResult(re:Object):void {
QopDump.echo(re);
}
function onError(er:Object):void {
QopDump.echo(er);
}
AS3 與 AMFPHP 1.2 part 2
後台傳送資料表至前端的「格式」
DataOp_2.php 原始碼
Flash AS3
正常執行的結果:
方法名稱錯誤的結果:
DataOp_2.php 原始碼
< ?php
class DataOp_2
{
var $dbhost = "localhost";
var $db = "test";
var $table = "tbl_address_book";
var $user = "root";
var $password = "admin";
function DataOp_2(){
mysql_connect($this->dbhost, $this->user, $this->password);
mysql_query("SET NAMES 'utf8'");
mysql_select_db($this->db);
$this->methodTable = array(
"getAllData"=>array(
"access"=>"remote"
)
);
}
function getAllData(){
$sql = sprintf("select * from `%s`", $this->table);
return mysql_query($sql);
}
}
?>
Flash AS3
import QopDump; // just prompt
var nc:NetConnection = new NetConnection();
nc.connect('http://localhost/amfphp/gateway.php');
var responder:Responder = new Responder(onResult, onError);
nc.call('myremoting.DataOp_2.getAllData', responder);
function onResult(re:Object):void {
QopDump.echo(re);
}
function onError(er:Object):void {
QopDump.echo(er);
}
正常執行的結果:
serverInfo:
version:1
id:
serviceName:PageAbleResult
initialData:
[0]:
[0]:3
[1]:哈利
[2]:0987654321
[3]:台北市大安區
[1]:
[0]:4
[1]:凱蒂貓
[2]:0987654322
[3]:宜蘭縣礁溪鄉
[2]:
[0]:6
[1]:小叮噹
[2]:0987654323
[3]:台東縣知本溫泉旁
columnNames:
[0]:id
[1]:name
[2]:phone
[3]:address
cursor:1
totalCount:3
方法名稱錯誤的結果:
line:171
description:The method {getAll} was not declared in the meta data for class {DataOp_2}.
level:User Error
details:C:\wamp163\www\amfphp\amf-core\app\Actions.php
code:AMFPHP_UNDECLARED_METHOD
AS3 與 AMFPHP 1.2 part 1
AS3 object serialization 預設為 AMF3, 後台若使用 AMFPHP 1.2
且要由 AS3 送資料紿後台時, 記得要設定成 AMF0 的格式溝通
且要由 AS3 送資料紿後台時, 記得要設定成 AMF0 的格式溝通
var nc:NetConnection = new NetConnection();
// 設定為 AMF0, 預設值為 AMF3
nc.objectEncoding = ObjectEncoding.AMF0;
nc.connect('http://localhost/amfphp/gateway.php');
2007-06-09
QopDump - Dump 的 AS3 版
改寫以前 AS2 的 Dump
使用方式
執行結果:
原始檔 QopDump.as
使用方式
var a:Object = ["sd","tg","rt",{a:"1", b:"23", c:"11"}];
// 取得字串資料用 QopDump.go(a)
// 直接 trace
QopDump.echo(a);
執行結果:
[0]:sd
[1]:tg
[2]:rt
[3]:
c:11
a:1
b:23
原始檔 QopDump.as
/**
* author: shinder lin
* email: shinder.lin@gmail.com
*/
package {
import flash.utils.describeType;
public class QopDump {
static var n:int = 0;
static var str:String;
// trace
public static function echo(o:Object):void {
trace( go(o) );
}
// return the result string
public static function go(o:Object):String {
str = "";
dump(o);
// remove the lastest \n
str = str.slice(0, str.length-1);
return str;
}
static function dump(o:Object) {
var type:String = describeType(o).@name;
if(type == 'Array') {
dumpArray(o);
} else if (type == 'Object') {
dumpObject(o);
} else {
appendStr(o);
}
}
static function appendStr(s:Object) {
str += s + '\n';
}
static function dumpArray(a:Object):void {
n++;
var type:String;
for (var i:String in a) {
type = describeType(a[i]).@name;
if (type == 'Array' || type == 'Object') {
appendStr(getSpaces() + "[" + i + "]:");
dump(a[i]);
} else {
appendStr(getSpaces() + "[" + i + "]:" + a[i]);
}
}
n--;
}
static function dumpObject(o:Object):void {
n++;
var type:String;
for (var i:String in o) {
type = describeType(o[i]).@name;
if (type == 'Array' || type == 'Object') {
appendStr(getSpaces() + i + ":");
dump(o[i]);
} else {
appendStr(getSpaces() + i + ":" + o[i]);
}
}
n--;
}
static function getSpaces():String {
var s:String ="";
for(var i:int = 1; i < n; i++){
s += " ";
}
return s;
}
}
}
2007-06-08
describeType() 是判斷型別的好工具
flash.utils.describeType() 是判斷型別的好工具
Flash AS3:
Output:
Flash AS3:
var a:Object = 123;
var b:Object = 1e-1;
var c:Object = {a:1,b:2};
var d:Object = [5,4,3];
var e:Object = 'sss';
trace(describeType(a).@name);
trace(describeType(b).@name);
trace(describeType(c).@name);
trace(describeType(d).@name);
trace(describeType(e).@name);
Output:
int
Number
Object
Array
String
把 JavaScript 當作 temporary data pool (AS3 和 AS2 溝通)
將 SWF9(from Flex2)收到的 Flashvars 變數, 傳給 JS
SWF8 需要時或被載入後再由 JS 取出
SWF9: AS3
JavaScript:
SWF8: AS2
JavaScript 的 alert() 有時也是個很好的除錯工具
SWF8 需要時或被載入後再由 JS 取出
SWF9: AS3
private var paramObj:Object;
private function init():void{
paramObj = Application.application.parameters;
ExternalInterface.call('setMyVars', paramObj);
}
JavaScript:
var myVars;
function setMyVars(v){
myVars = v;
/*
var s='';
for(var i in v){
s+= i+' : '+v[i]+'\n';
}
alert(s);
*/
}
function getMyVars(){
return myVars;
}
SWF8: AS2
import flash.external.ExternalInterface;
var myVars = ExternalInterface.call('getMyVars');
JavaScript 的 alert() 有時也是個很好的除錯工具
AS3 和 AS2 溝通
Adobe CS3 才上市不久, 大部份的人對 Flash CS3 不是頂熟稔
若要使用 ActionScript 3 的新功能, 卻又想以熟悉的 Flash 8 開發
遇到的最大問題就是 ActionScrip 3 和 ActionScript 2 的溝通
目前常用的作法有兩種: LocalConnection 和 ExternalInterface
在使用 SWF 9 (from Flex 2) 載入 SWF 8 (from Flash 8) 的情況下, 使用文字資料做測試
LocalConnection 每次只能傳送低於 40K 的資料
透過 ExternalInterface 則可以傳遞超過 1M 的資料給 JavaScript
LocalConnection 明顯只適用於傳遞少量資料
缺點: 接收的 SWF 實體只能有一個 (第二個實體之後是收不到資料的)
優點: 不限實體的執行形式 (EXE, flash player, flash plugin)
ExternalInterface 的缺點是必須要有 plugin container 當中介的角色
之前遇到的一個情況是 SWF9 載入兩支 SWF8 (a 和 b)
● SWF8a 負責和使用者互動, 讓使用者編輯
● SWF8b 負責產生上傳的圖片
● SWF9 負責將 SWF8b 的內容上傳
SWF8a 透過 EI 傳遞 XML 給 SWF8b 產生圖片
SWF8b 完成圖片後, 透過 EI 叫 SWF9 上傳圖片
SWF8a: AS2
JavaScript:
SWF8b: AS2
SWF9: AS3
若要使用 ActionScript 3 的新功能, 卻又想以熟悉的 Flash 8 開發
遇到的最大問題就是 ActionScrip 3 和 ActionScript 2 的溝通
目前常用的作法有兩種: LocalConnection 和 ExternalInterface
在使用 SWF 9 (from Flex 2) 載入 SWF 8 (from Flash 8) 的情況下, 使用文字資料做測試
LocalConnection 每次只能傳送低於 40K 的資料
透過 ExternalInterface 則可以傳遞超過 1M 的資料給 JavaScript
LocalConnection 明顯只適用於傳遞少量資料
缺點: 接收的 SWF 實體只能有一個 (第二個實體之後是收不到資料的)
優點: 不限實體的執行形式 (EXE, flash player, flash plugin)
ExternalInterface 的缺點是必須要有 plugin container 當中介的角色
之前遇到的一個情況是 SWF9 載入兩支 SWF8 (a 和 b)
● SWF8a 負責和使用者互動, 讓使用者編輯
● SWF8b 負責產生上傳的圖片
● SWF9 負責將 SWF8b 的內容上傳
SWF8a 透過 EI 傳遞 XML 給 SWF8b 產生圖片
SWF8b 完成圖片後, 透過 EI 叫 SWF9 上傳圖片
SWF8a: AS2
import flash.external.ExternalInterface;
ExternalInterface.call("toRender", _xml.toString());
JavaScript:
function toRender(str){
if(navigator.appName.indexOf("Microsoft") != -1){
window.room_planner.renderPic(str);
}else{
window.document.room_planner.renderPic(str);
}
return true;
}
function uploadImage(){
if(navigator.appName.indexOf("Microsoft") != -1){
window.room_planner.uploadImage();
}else{
window.document.room_planner.uploadImage();
}
return true;
}
SWF8b: AS2
import flash.external.ExternalInterface;
var successRegist = ExternalInterface.addCallback("renderPic", null, render);
//
function render(d_str) {
// loading objects ...
onEnterFrame = sdEnterFrame;
}
function sdEnterFrame() {
var all_loaded = true;
for (var i = 0; i < loadee_ar.length; i++) {
if (loadee_ar[i].c_mc.getBytesLoaded() < 10) {
all_loaded = false;
break;
}
}
if (all_loaded) {
resizeToUpload();
ExternalInterface.call('uploadImage');
delete this.onEnterFrame;
}
}
SWF9: AS3
private function init():void{
// ...
ExternalInterface.addCallback('uploadImage', uploadImage);
}
private function uploadImage():void{
pop = PopUpManager.createPopUp(this, MyMsgWin, true);
pop.x = 440;
pop.y = 296;
var timer:Timer = new Timer(500, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, doUploadImage);
timer.start();
}
訂閱:
文章 (Atom)