2011年2月17日 星期四

numChildren屬性對應子物件數量的正確性

在Flash IDE上設計好的物件,如果要利用AS取得該物件下的子物件數量
通常會是透過numChildren取得子物件數量,例如ball.numChildren

但有可能會有讀到的numChildren值,與你在Flash IDE上放置的子物件數量值不同的問題。

這情況會發生在,當在Flash IDE上設計子物件時,把多個Shape物件(也就是並未轉成Symble),放在一起(在IDE上把多個Shape放在同一個Layer上或把多個Shape放在相鄰Layer上),這時候這些相鄰的Shape,不管數量有多少,都只會被當作一個子物件計算,這時numChildren取得子物件數量就會與在IDE上放的子物件數量不同

如果Shape間有被TextField物件或其他Symble間隔開來,則numChildren可讀到正確的子物件數量,
或是將繪製的物件轉成MovieClip就可以正確讀出

2011年2月9日 星期三

今年過年

醫院
年前老爸送長庚急診,大概是過年大家都要出院回家
大弟只在急診室等了一夜,等我到醫院時 就排到了病床
我們兄弟輪替著在醫院陪著,
在回到家的這幾個晚上,我都在醫院陪著

老爸睡的不好,有時候整晚沒睡,需要靠安眠藥才能休息
有時因藥物的副作用讓他痛的無法入眠
很自然的,我的睡眠也就斷斷續續

每天一早7點老爸就會起床吃藥.
拉開窗戶的百葉窗, 這是一天的開始
白天有機會休息時,就躺在旁邊的躺椅上
也許是小睡片刻,也許是看看書,或者是看著外面的天空
想著許多許多的事 看著窗外一片美麗的藍

買彩卷
快中午,小弟就到醫院來,我也偷了個空
早點回家抱抱妹妹
帶老婆去剪頭髮,說好打電話來 我再去接他

在家跟妹妹玩,看看時間差不多了
騎著摩拖車載妹妹去找媽媽
媽媽在髮廊斜對面的彩卷行,
聽說這期有11億,當然也要跟人去碰碰運氣
買了400塊的刮刮樂,還中了700,今年的運氣還真是有點不錯
坐在彩卷行的椅子上,一家人開心的對獎,
喝著老闆請的飲料
明亮的陽光 大好的天氣
有一種幸福的感覺

除夕夜
原本該是全家團聚的時間
去年的這個時候,還聽著老爸講著似乎每年都相同的故事
老婆本來還說要聽看看老爸今年講的是否一樣
只是這個夜
只有老媽 小弟還有我一家吃著晚餐
大弟在醫院陪著老爸

簡單的吃了飯,小弟開車載著我們到醫院
今天晚上他會陪爸

醫院裡冷冷清清,大家都趕在過年前出院請假回去了
圍在爸身邊看他有點清醒的樣子
我們大家把紅包放到他上衣的口袋
爸 過年了 新年快樂

初一
習慣在大年初一跟著家人到廟裡拜拜
也感受那比較濃厚的過年氣味

鼓山亭 大火後重建 已經恢復整個廟宇的建築
只是已經失去原本古樸的外觀
遇到了八叔,問起爸的狀況,簡單的回應有好了一些

在成功路上繞了一下
才找到了 蘇府王爺廟,附近都蓋了新大樓
也大概是自己太久沒回去了,指憑著記憶要找到那在大樹旁的廟
越來越難

傍晚媽煮飯 怕妹妹在旁邊吵
騎著車到文化中心晃晃
老婆悠閒的逛著廣場上一個個的年節攤位
妹妹在廣場旁的階梯上,上上下下並玩著拔草亂撒的遊戲
一直到老婆帶著滿手的零食 一家人吃完後,才盡興的回家

明天就要回台北了
8點多再騎車去去長庚 看看爸
今天晚上 是大弟還有他老婆在醫院看顧
和大弟 聊阿聊的 10點半多載大弟一起回家
回家路上 大弟帶我到瑞隆路上 買了好吃的豆漿燒餅
這是份暖暖的宵夜

初二
小弟開著車帶我們到高鐵站
滿滿的乘車人潮,等了會才有位子在摩斯吃早餐
要回台北了 一堆的工作等著
只希望 在南部的家人 可以 健康平安

2011年1月27日 星期四

以SWF為Skin的程式設計

預期開發功能
1.Flash主程式與視覺外觀部份分離
2.外觀部份為以Flash IDE設計輸出swf檔案,當作主程式外觀Skin
3.Skin部份,設計師可任意排列物件
4.各個Skin,允許部份元件不存在
5.在程式進行當中,可任意更換Skin

一.Skin Loader
在利用Loader載入外部swf當作skin時,因為要當作skin用的swf內必定都會有著相同的物件名稱。例如skin01.swf與skin02.swf內都會有著同為bg的物件,這時在設定loader的LoaderContext時需設定其
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
讓載入的物件Class屬於主體ApplicationDomain下的子系,才能讓每次載入不同swf的Class都能生效
如果使用
context.applicationDomain = ApplicationDomain.currentDomain;
會讓所有的Class都掛在主體ApplicationDomain下,這時後當重新載入新的swf時,檢查到ApplicationDomain下該物件名稱Class已經存在,則會使用原有的Class,所以新載入的swf內同名物件永遠無法載入,只會一直載入舊有的Class
就無法達到動態換Skin的作用

例
var loader:Loader = new Loader();
var request:URLRequest = new URLRequest(_swfPath);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
loader.load(request,context);

二.Skin內使用物件Class設計
在Skin內要用到的物件,在設計Class時,不要在建構子內放置物件的初始化動作
(因為產生物件時,可能還沒有實體內容載入),而是將初始化的動作放在一個如
init()的public method內,在確認物件存在的狀態再執行init()即不會出錯

例
public function Banner(){}
public function init():void {
    setView();
    setListener();
}
private function setView():void {}
private function setListener():void {}

三.Skin Swf在Flash IDE上的設定
1.設定一個AssetContainer,用來設計Skin Layout
通常利用loader載入swf當作library來使用物件,都是利用在物件上linkage設定Class後來取得物件使用,但若這樣在程式裡產生物件使用,Layout部份,就需要寫在程式碼裡去做排列,但這樣就無法讓視覺設計去自行設計版面排列。

可以在fla內設定一個MovieClip當作AssetContainer來用,設計師在這個Container內排列所要的物件,與所要的排列方式,
透過loader載入swf後,取得這個AssetContainer物件的Class,再由這Class內,透過getChildByName,取得所有物件,各物件即已經存在有位置大小等屬性

例
在Fla的library內設定AssetContainer Linkage Class

var AssetContainer:Class=loader.contentLoaderInfo.applicationDomain.getDefinition(className)  as  Class
_assetLib = new AssetContainer();
mybg=_assetLib.getChildByName("bg");
mybg.init();

2.在Linkage對物件設定Class時,建議都在Class上指向完整Clss,Base Class都是MovieClip
若有需要用到相同物件,因為Class只能指定給一個物件,若有其他需要,可以extends Class出來使用即可

3.繼承自Components的元件需更改元件Linkage Class
若元件繼承自Components,在將component拉到library內後,在components上的linkage的Class改成自訂Class name
例如自己設記一個繼承自List元件的Class MyList,在Fla內需先把List元件拉入Library內,
再修改List元件的linkage的Class為MyList

四.主程式
1.物件參考變數設定
在主程式中,用來當作物件參考的變數,在重新載入Skin後即會失效
要讓物件參考變數再度指向物件參考需透過getChilByName取得才能保證取到物件

例如
在swf內有一個 instance為book的Book物件
當重新載入skin時,這個book變數並不會自動指向新取代而來的物件
需要透過
book=app.getChildByName("book")來讓變數指到實體的物件

2.不同SKin允許部份元件不存在
可能會需要在不同的Skin中允許部份的元件不存在或不使用
在可能會因為物件不存在而造成錯誤的地方,先用
if(obj!=null)做檢查再執行

2010年12月24日 星期五

網頁與AIR程式互動

如果需要在Browser上可以與AIR應用程式做互動,如安裝AIR App,或由網頁上的Click觸發啟動AIR App,以下是相關執行程序

一.準備工作
1.AIR程式端設定AIR程式允許透過Browser觸發
設定AIR發布用的application.xml的
 <application xmlns="http://ns.adobe.com/air/application/2.0">  
建議設定發布為AIR 1.53以上版本,因為如果AIR為1.53之前的版本,Browser要呼叫AIR,一定要知道AIR的PID值(在AIR內可以用NativeApplication.nativeApplication.publisherID取得)。若AIR為1.53後的版本,若Browser不知道AIR的PID,可以用""代即可。

加入
 <allowBrowserInvocation>true</allowBrowserInvocation>  
讓AIR允許被Browser啟動

2.Browser端Flash取得AIR Browser API
Browser端Flash要操作AIR所要用的API都放在http://airdownload.adobe.com/air/browserapi/air.swf內
透過loader載入這個檔案即可使用相關功能

public var airSWF:Object;
public var airSWFLoader:Loader = new Loader();
public var loaderContext:LoaderContext = new LoaderContext();
loaderContext.applicationDomain = ApplicationDomain.currentDomain; 
airSWFLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit); 
airSWFLoader.load(new URLRequest(" http://airdownload.adobe.com/air/browserapi/air.swf"), loaderContext);
private function onInit(e:Event):void { 
    airSWF = e.target.content;
    airSWF.getApplicationVersion(appID, pubID, versionDetectCallback);
}        

二.Browser檢查Client是否已經安裝AIR執行環境
var result:String=airSWF.getStatus();
取得回傳值
"available":可安裝但尚未安裝。
"unavailable":無法安裝
"installed":已安裝

三.Browser檢查Client端是否已經安裝AIR 應用程式
利用檢查AIR應用程式版本來確認程式是否已經安裝,執行後,若檢查完成
會呼叫執行所設定的versionDetectCallback函式,並在這callBack函式內
取得版本值,當版本值為null代表未安裝程式
airSWF.getApplicationVersion(appID, pubID, versionDetectCallback);
private function versionDetectCallback(version:String):void { }    

設定參數:
appID:應用程式ID,即AIR應用程式的application.xml內的id值,或在air內透過
    NativeApplication.nativeApplication.applicationID取得
pubID:發佈者ID,在air內透過
    NativeApplication.nativeApplication.publisherID取得

注意:要讓這功能有效可以使用,在使用air.swf一定要是載入http://airdownload.adobe.com/air/browserapi/air.swf
若將這air.swf複製到local端呼叫使用,則取得版本永遠會是null值

四.Browser安裝AIR App
airSWF.installApplication(installPath, runtimeVersion, arguments); 
設定參數:
installPath:String,要安裝的air檔案路徑
runtimeVersion:String,允許執行的AIR Runtime最低版本,例如"1.5"
arguments:Array,非必填項目,要傳遞給AIR的參數,這參數會被AIR內的
BrowserInvokeEvent.BROWSER_INVOKE事件所接收

五.Browser 啟動已安裝AIR APP
airSWF.launchApplication(appID, pubID, myArguments);

六.Browser傳遞參數給AIR App
airSWF.launchApplication(appID, pubID, myArguments);
只要將傳遞的參數放到myArguments陣列內即可