網頁

顯示具有 ActionScript 標籤的文章。 顯示所有文章
顯示具有 ActionScript 標籤的文章。 顯示所有文章

2011/08/21

ActionScript中的傳值與傳址

今天在看DS發現了一個滿有趣的問題,要怎麼使用ActionSript使用傳址的而不是傳值到函數之中。會這麼想是因為如果使用c語言可以使用指標,但是在as中並沒有這樣功能。

Consider the as function:
var a:int = 1;
var b:int = 2;
swap(a,b);
trace("a:" + a + ",b:" + b); //a:1,b:2

public function swap(num1:int,num2:int):void {
   var temp:int = num1;
   num1 = num2;
   num2 = temp;
}

trace出來會變成「a:1,b:2」,因為是將值丟到swap這個function時,會將a、b複製一個複本給swap的num1,num2,而不是原來的a、b,這樣稱之為「傳值」。如果是c語言就可以直接傳址進去,直接將a、b兩個變數直接交換,由於是直接指向記憶體,稱之為「傳址」。

但在as之中要怎麼辨到傳址的功能呢?它並沒有像c一樣的語法「*、&」可以使用,於是查找了官方文件找到「函數參數」,原來可以包裝成物件,在as中物件是以傳址的方式進行的。

Instead of the code:
var num:Object = {a:1,b:2};
swap2(num);
trace("a:" + num.a + ",b:" + num.b); //a:2,b:1

public function swap2(num:Object):void{
   var temp:int = num.a;
   num.a = num.b;
   num.b = temp;
}

噢,太好啦,終於達到我想要的效果了,可以將兩個變數交換過來了。使用傳址的好處之一是記憶體會較省空間,因為不需要在copy另外一個複本給function(當然區域變數使用完會釋放掉),如此推斷在執行的速度也會比較快,少掉了複製複本的時間。這讓我想到在OOP的撰寫時通常會寫一個Value Object(VO)來描述一個物件的Data Structure,除了可以將資訊做一個整理外,在傳輸時也可以用傳址的方式來處理,這也算是另外一個好處之一吧。

結論:
.自訂類別、物件是使用傳址而非傳值。
.基本物件型別(Boolean、Number、int、uint、String)為傳值而非傳址
.使用傳址會較省記憶體空間,且速度較快
.Array是物件,所以也是傳址

2011/08/20

發佈一些常用的類別




整理了一下之前撰寫的一些常用AS小工具,將原始碼放到了Github了,有興趣的人可以下載來使用囉~Download Source Code

Git是版本控制的一個方法,可以參考下面的文章與簡報:
Ihower
初學筆記 - 指令操作教學
用Git與Github管理軟體開發專案
Git Internals PDF ebook
Pro Git

2011/08/09

PureMVC重點整理

主要參考資料來源:
學習過程中感謝前輩們的資料,前人種樹、後人乘涼啊~以下為研究PureMVC時都會練習的Best Practices的重點整理,因為老是看了後面會忘記前面,是老了嗎...。

1.概念
  • MVC的代理分別為Proxy、Meditator、Command
    • Model<->Proxy
    • View<->Meditator
    • Controller<->Command
  • Facade and Core。
    • 單態模式Singleton。
    • 主要用來初始化MVC核心
    • 使Proxy、Meditator、Command可以互相拜訪
  • 使用Observer/Notification來實現內部溝通。
    • Facade 保存了Command與Notification間的映射。
    • 發送Notification->執行對應Command
    • Meditator發送、聲明、接收Notification
    • Facade、Proxy只能發送,但不接收Notification
2.Facade
  • Model、View、Controller三者的經紀人。主要訪問通知Proxy、Meditator、Command
  • Facade永不被實例化。應編寫成子類orwgn or 添加重寫Facade。
  • 除了頂層的Application,其它視圖不應該和Facde互動。
  • 使用。直接看Best Practices較清楚。
3.Notification
  • 實現觀察者模式。
  • 發送時可以帶一個「body」參數,可以是任何對向。
  • 另外可帶另一「type」參數,讓接收者作為識別的依據。
  • 可另外自已定義一個Notification。
  • 公用Notification常數名稱通常寫在Facade中。寫成常數避免打錯字的錯誤情況。
4.Command
流程:
  1. Controller 註冊監聽每一個Notification
  2. 事件發生通知
  3. Controller實例化Notification對應的Command
  4. Notification傳送參數給Command,並執行execute
重點:
  • 需要時才被創建,使用後即拋棄。(不要在生命周期長的物件中引用Command對象)
  • 用來協調Model與View
  • SimpleCommand執行單一命令。
  • MacroCommand執行多項命令。使用addCommand添加子Command。
  • 可以任意組合SimpleCommand、MacroCommand。
  • Model應封裝Domin logic、Command處理Business logic

5.Meditator
  • 主要處理View Component派發的事件和其它系統外發出的Notification訊息通知
  • 常將Proxy實例保存於屬性中,避免頻繁獲取Proxy實例。
  • 建構式提供兩個參數name和objec對象,object會將值給予viewComponent(protected)屬性。之後可以使用getter將object轉化成合適的型別。
  • 通常一個Meditator對應一個View Component,若其它包含多個子組件,請封裝Component對外的操作。
  • 接收事件後可能處理情況有:
    • 檢查類型或事件自定內容。
    • 檢查修改View Component屬性。
    • 檢查修改Proxy公布的屬性。
    • 發送一或多個Notifiction給Meditator or Command。
  • 實用小技巧
    • 多個Meditator對同一事件監聽,應發送一個Notification,不同的Meditator做各自的處理。
    • Meditator需要對其它Meditator作互動,最好的方法是用Command將步驟定義在一個地方。
    • 不應該讓一個Meditator去調用其它的Meditator。這是錯的!!
    • Proxy->更新狀態->Notification通知->Meditator反應到視圖。
  • 處理事件的方法:
    • Meditator初始化時會在listNotificationInterests方法中註冊感興趣的事的常數。
    • Meditator接收到感興趣的事件時,會叫用handleNotification方法。
    • 最好將所有的Notification處理方法放在handleNotification,並使用switch/case而不是if/else。
    • 處理的事件應在4、5個之內。太多則意味還Meditator還需要拆分。
    • View依賴Model、Model不應依賴View。
    • 使用Command、Notification來實現View與View的鬆偶合。
6.Proxy
主要用來管理程序數據模型,可能會有下列幾種類型:
  • Remote Proxy
  • Proxy and Delegate
  • Protection Proxy
  • Virtual Proxy
  • Smart Proxy
轉換數據對象
  • 建構式接受一個名稱name與object的參數,Object用來設置Proxy的數據模型,亦可始用setData設置
  • 使用getter將Data Object轉成真正的型別。
  • 不監聽Notification而是發送。
  • 將Domain Logic寫在Model,之後重構才不會使Model層引嚮到View或Controll。
  • 不應該引用、操作Meditator。

2011/03/09

菜鳥的PureMVC筆記(1)

最近參加了Flash/Flex/AS精武讀書會,聽完高手們的分析解釋外加自已努力鑽研,結論是PureMVC真是難以下嚥,快吐血身亡了…Orz,看了許多次才能大致了解它的框架各個部分是在做什麼的,若沒有學過設計模式(Design Pattern)很難捉到PureMVC的精神。基於我是PureMVC菜鳥要有菜鳥勉強的方法,因此構想出在學習PureMVC前預先要了解的知識清單。

1.了解什麼是設計模式?
2.與PureMVC相關的設計模式?
  • Singleton Pattern 單態模式
  • Observer Pattern 觀察者模式
  • Composite Pattern 組合模式
  • Facade Pattern 外觀模式
  • Mediator Pattern 仲介者模式
  • Command Pattern 命令模式
  • Proxy Pattern 代理人模式
3.其它不能不知道的設計模式。
  • Strategy Pattern 策略模式
  • Factory Method Pattern 策略模式
  • State Pattern 策略模式
3.MVC(Model-View-Controller)複合模式
4.開始學習PureMVC---> 還不是很熟目前沒有要寫,熟一點在來搞,所以標題是大誤 ~ XD

以下列出我學習設計模式時參考的書籍:
深入淺出設計模式 
深入淺出設計模式 (Head First Design Patterns)
 雖然這本書是用Java來做例子,但整本書淺顯易懂,是我學設計模式買的第一本書。

物件導向設計模式 
物件導向設計模式 Design Patterns 由GoF四人幫所撰寫,是學習設計模式的聖經。

ActionScript 3.0 Design Patterns
 ActionScript 3.0 Design Patterns 我比較喜歡這本,因為是用ActionScript3.0實作Design Pattern比較容易上手測試程式碼。



continue soon...{(It's too late)? go bed:continue}

2011/03/04

My Log Message

前幾天在找資料時,看到這一篇官方說明文件「基準測試」的文章,裡頭用到滿多偵測效能或是as開發時debug的工具,裡頭有一個修件編譯的功能讓我滿好奇的,可以在Complier時選擇是程式碼是否要編譯,上網查了資料,相當感謝奶綠茶所寫的的這一篇文章「使用condition compiling」才能快速了解它的使用方法和找到相關的資源,於是便想到寫一個小trace工具(Log),我希望它能夠有顏色辨識的功能並且能設定字型的大小,所以是用textHTML來設定文字,縮排的話可以使用「\t」的方式來解決,這樣應該就可以滿足大部分的需求,另外希望可以一開始時畫面上不會顯示這個物件而是按Ctrl+Shift+L來切換Log的visible屬性,Log也可以隨視窗大小而改變。另外我只有定義CONFIG::debug,true,而沒有定義CONFIG::realease,false,主要是因為發佈時把CONFIG::debug,true改成false就可以不用在編議log的程式碼了。

雖然目前可以直接使用滑鼠滾輪直接捲動文字,但想接下來也許可以製作拉吧之類的功能,設定文字也可以設較多樣性的方法來顯示。


使用方法:
var tracer:Log = Log.getInstance();
stage.addChild(tracer);
tracer.setMessageByHTML("test1", 12, "#00ff00");
tracer.setMessageByHTML("\ttest2", 13, "#ff0000");
tracer.setMessageByHTML("test3", 14, "#0000ff");


搞定來睡,版面有點醜想換一個 = =


2011/02/10

My Video Note

文章來源為ActionScript Cookbook,本文為在下讀書的摘要。

最近複習了一下State Pattern,剛好書上是使用video來講解,順便整理一下播放影片類別之間的作用。

flash.net.NetStream  -> 負責載入和控制播放。
flash.media.Video  -> NetStream只關心資料移動,Video可以將NetStream中的資料呈現在螢幕上。
flash.net.NetConnection  -> NetStram需要NetConnection求出資料的源頭,源頭有兩種:
  • Flash Communication Server 或 Flash Media Server:NetConnection會指向伺服器。
  • 本地:NetConnection成使用null。

了解以上的類別的功用後,以下為建立影片之必要程式碼 –

Step 1 – 建立一NetConnect物件,並指向null,表示影片來源為漸近式的影片(參考)
var nc:NetConnect = new NetConnection();
nc.connect(null);

Step 2 – 建構NetStream物件
var ns:NetStream = new NetStream(nc);

Step 3 – 建立Video物件,並顯示在顯示清單中
var video:Video = new Video();
addChild(video);


Step 4 – 將NetStream加入video視訊
video.attachNetStream(ns);

Step 5 – 最後播放影片的方法
ns.play("example.flv");


直接動手建立video還滿麻煩的但是很輕巧,而我現在做專案為了趕時間通常直接使用FLVPlayback組件,這樣比較快但笨重。



備註:
ns.close() -> 停止播放串流上的所有資料、將 time 屬性設定為 0,並讓該串流可以用於其它用途。
video.clear() -> 清除目前顯示在 Video 物件 (而非視訊串流) 中的影像

2011/02/06

ActionScript中的音效控制(一)

Demo
Download:Source Code.
Tool:Flash Develop
Image:Icon Flider
Sound:Flash Kit

在製作Flash遊戲(或網站)時有時會播放一些音效或音樂,並且有控製聲音的按鈕,可以切換聲音的開關來控製整體的音效,想要放在某一類別進行控製,而不是將程式碼散置在各處,也許可以使用設計模式中的單態模式(Singleton Pattern)來實現這些功能。

【tw/com/birdnest/SoundController.as】
Step 1.一開始建立SoundController類別,使用Singleton Pattern的好處之一是不必擔心實例化許多物件而造成聲音互相重疊或不易控製。



Step 2.加入聲音addSound方法。這裡使用關連陣列加入每個Sound物件,些範例是直接需要用到的音效的路徑參數直接寫在SoundController,我想在遊戲的實作中應該需要有一個專門處理初始值的物件來處理這一塊會較好,畢竟遊戲中會用到的元素並不一定只會有聲音。
範例中我使用BACKGROUND_MUSIC_URL、BACKGROUND_MUSIC_NAME…等常數來避兔打錯字。



Step 3.播放聲音playSound方法。還滿單純的,直接使用for...in來找目前需要播放那一個音樂/音效。



Step 4.關閉所有聲音closeAllSound方法。SoundMixer.stopAll()靜態方法可以直接將所有的聲音關閉。



Step 5.打開聲音openSound




除了上列的方法以外,遊戲中可能也會有其它需求,像是調背景音樂或音效大小、聲音位移的位置之類的功能,我想應該也可以加入一些方法來實作,目並還沒有實作這樣的功能。


使用方法:
【tw/com/birdnest/Main.as】
單純播放閃電的音效。
SoundController.getInstance().playSound(SoundController.THUNDER_BUTTON_SOUND_NAME);

【tw/com/birdnest/SoundButton.as】
建立一個開與關的功能,將所有的聲音開與關。

2011/01/29

翻牌遊戲的洗牌方式

最近在研究翻牌遊戲洗牌的方式,首先想到的是需要兩兩相對的牌數,比如場上有10張牌,我想要得到0,0,1,1,2,2,3,3,4,4樣的數序列,根據這樣的數列使牌與牌能相對應。在數學(Math)的方法所可以找到三個函數:

.Math.round()–四捨五入
.Math.ceil()–無條件進位(ex.1.1=2、1.8=2)
.Math.floor()–無條件捨去(ex.1.1=1、1.8=1)

因此,使用迴圈來達到這樣效果,先給0-9數字除以2再取floor:



如此一來,我們在場上就有兩兩相對應的10張牌,接著在對場上的牌做洗牌的動作,先用亂數取出目前陣列某一數,塞到陣列的屁股後,在刪除原來的數:




最後便得到洗牌後的亂序數列。

2009/03/19

使用外部檔案庫

之前在為嵌入字體的事情而煩惱,但也因此學會了如何使用外部檔案庫,讓人收獲頗多。因為要開始進行一個專案時,就可以將界面設計、圖片、聲音…等資料集中在一起管理,而且之後的維護只需要修改檔案庫裡面的內容發佈後就可以了,程式與美術也可以分開製作,除了可以節省時間對整體的設計也多了彈性,真的是一舉數得,這其中還學會了如何製作 Flash 組件、了解source-path,liberary-path與external-library-path之類的不同。這個也可以應用在遊戲上,可能之後我就搞一個檔案,讓美術那邊自由自在的在原始檔內創作,發佈後我抓取裡面的資料就可以了。以下為建立的步驟:

1.建立一個library.flv,類別文件設定為「Library」,元件庫內含所需要的元件,並個別設定好Linkage>Class。

2.建立Library.as,內含取出元件庫物件的方法。此步驟也可以略過,直接在第三個步驟取得元件。

3.使用loader載入library.swf後,使用getDefinition(),取得類別或元件的關聯並產生實例即可。

範例下載。

2009/03/09

MageZine3

公司的產品一直是以電子書為主,但核心一直是使用AS2寫的,因此不時會尋找更新的版本,最近找到了的電子書「MageZine」,程式核心便是用了AS3.0來撰寫,試用了一下效能與效果有不錯的表現,重要的是:它是免費的,當然需要他們的技術支援的話可以付一些費用給他們。有興趣的話可以到官網了解相關的資訊。

下載之後可以看到下列檔案結構目錄:

.bin 輸出檔
 - megazine 放置圖片、聲音、xml設定資料、swf版型…等
 - swfaddress 讓全Flash的網站,每個單元有獨立的網址
 - swfobject 可以用來偵測版本、簡單嵌入swf檔
 - index.html 主要電子書的HTML頁面
.src 程式原始檔
 - com 外部類別
 - de magezin類別檔
 - fla 嵌入影片與swf的容器檔
 - org 與gif相關(目不不明白其用途)
.tools 似乎可以將電子書內容轉成pdf的.bat批次檔

參考網址:
 SwfObject:
 MegaZine3:
 Forum
 Quick Start