Refactoring in AS3
最近連續兩場上台講話,深深覺得自己的口條跟講話的速度還得再好好的修練。這是今天在同業的AS聚會上講的內容 Refactoring in AS3
另外這是在上星期的Flash聚會分享的 AS3 Better Practices
有需要歡迎取用 :)
最近連續兩場上台講話,深深覺得自己的口條跟講話的速度還得再好好的修練。這是今天在同業的AS聚會上講的內容 Refactoring in AS3
另外這是在上星期的Flash聚會分享的 AS3 Better Practices
有需要歡迎取用 :)
=====
前言
=====
常聽很多朋友會問:「flash要怎麼樣跟資料庫串接?」
答案其實很簡單:「不行!目前flash沒辦法直接與資料庫串接」
那到底別人是怎麼做的,為什麼他們的flash可以由後台管理然後更新資料?
flash(*.swf) <--> Server端程式(asp, .net, php…etc) <--> DB
*.swf透過HTTP GET/POST的方式送給中間的程式
透過中間的程式,flash才得以從資料庫中取出/寫入資料
其中*.swf與server端程式溝通的格式,有簡單的純文字組合
或是用JSON或XML來包裝資料,再餵給*.swf,最後再呈現在flash上
特別是XML對AS3還滿友善的,可以簡單的就取出指定節點的資料
而今天要提的 AMF(Action Message Format)
其實做的工作跟上面的JSON或XML差不多,只是它的格式是binary的
AMF的實作,各家程式語言或Framework都有類似的實作品
像是PHP就有AMFPHP/Zend_Amf,Python有PyAMF,.NET有FluorineFx,Ruby的話則有RubyAMF
不過不管是哪家實作的AMF,流程上都差不多:
1. *.swf連上指定的Gateway
2. 呼叫/執行Gateway上掛載的service,並把所需的參數以AMF格式傳給它(如果有的話)
3. 執行結果回傳
最近手邊有個案子正好是用Rails寫的,剛好有用上AMF,就趁這個機會寫一下心得,免得自己以後忘記
(其實在Rails裡面,用respond_to直接render產出xml或json也還滿方便的...)
=====
環境
=====
Mac OX 10.6
Rails 2.3.5
ruby 1.8.7
RubyAMF 1.6.5
=====
安裝
=====
就不多做Rails的介紹了,直接開個空白的Rails Project來做示範
> rails rubyamf_demo
> cd rubyamf_demo
接下來,安裝RubyAMF
網址:http://code.google.com/p/rubyamf/
個人比較建議直接用script/plugin來安裝,簡單方便
當然如果要自己下載打包檔再手動放進來也ok的
> script/plugin install http://rubyamf.googlecode.com/svn/tags/current/rubyamf
沒問題的話,這個動作就會幫你把rubyamf安裝在vender資料夾裡了
其實這個安裝的過程中,除了把相關檔案裝到vender裡之外,背後有幫忙做了一些事你可能需要知道的:
1. app/controllers/ 裡多了一個rubyamf_controller.rb
這是整個amf的對外窗口,gateway就是寫在這裡了
2. config/ 裡多了一個 rubyamf_config.rb
RubyAMF的設定檔,打開這個檔案應該可以看到許多註解說明,可依情況及個人使用習慣做調整
3. config/initializers/mime_types.rb多加了一行
Mime::Type.register "application/x-amf", :amf
到時候可以像 render :text => "hello"一樣,直接用render :amf => "hello"來輸出
4. config/route.rb多了一行路徑設定
map.rubyamf_gateway 'rubyamf_gateway', :controller => 'rubyamf', :action => 'gateway'
gateway到時候的位置就是http://127.0.0.1:3000/rubyamf/gateway
5. public/ 資料夾多了一個 crossdomain.xml
常用AS在串接外部資料的人應該知道這是幹嘛的了,預設是全開
<allow-access-from domain="*" />
如果有需要調整可直接動手修改
接下來試著啟動server,看看能不能正常運作
> script/server
沒問題的話,接著開瀏覽器看看
http://127.0.0.1:3000/rubyamf/gateway/
如果你看到一個黑色的畫面,中間放著一個RubyAMF的logo
恭喜你,目前這樣就算是把RubyAMF安裝起來了
接下來,就要開始準備寫service上去了
=====
實作
=====
Rails部份:
先建立一個model,待會我們會用來取出/寫入資料用的
> script/generate model book author:string content:text
目前只放了author跟content兩個簡單的欄位
(for demo purpose, model部份沒有特別做validation)
> rake db:migrate
為了省去另建資料庫的麻煩,這裡直接使用預設的SQLite做為資料庫
table建立後,先塞一筆測試資料進去
> script/console
>> Book.create(:author => "eddie", :content => "this is a RubyAMF demo")
再來新增一個controller,裡面放一個hello_world這個action
> script/generate controller amf_test hello_world
在hello_world這個action裡,我們加一行:
def hello_world
render :amf => "Hello AMF"
end
大部份網路上看到的範例都是用Flex當範例,不過我個人比較偏好Flash
以下我就用Flash當做範例示範(其實沒太大差別啦,純粹個人喜好)
Flash部份:
範例檔案下載:amf_hello.fla
var nc:NetConnection = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF3;
nc.connect('http://127.0.0.1:3000/rubyamf/gateway');
var responder:Responder = new Responder(onOK, onErr);
nc.call('AmfTestController.hello_world', responder);
function onOK(res:Object):void
{
trace(res);
}
function onErr(res:Object):void
{
trace("Error!");
}
其中比較需要注意的是nc.call那一段
直接呼叫ControllerName.ActionName就行了
按下Ctrl+Enter之後,應該就可以看到"Hello AMF"的字樣了
代表你的swf已經可以成功從AMF Gateway讀資料回來了
如果這裡有發生錯誤,可能檢查一下是不是有打錯字,或是server忘了啟動
接下來,我們試著送資料給gateway,讓它寫入資料庫之後再回傳目前資料庫裡的書總共有幾本
這次我們先做flash端的介面,我放了一個按鈕跟二個輸入框
instance name分別取名為add_btw、author_txt及content_txt
(檔名:amf_addbook.fla)
AS3語法如下:
add_btn.addEventListener(MouseEvent.CLICK, click_handler);
function click_handler(evt:MouseEvent):void
{
var nc:NetConnection = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF3;
nc.connect('http://127.0.0.1:3000/rubyamf/gateway');
var amf_object:Object = {
'author': author_txt.text,
'content': content_txt.text
};
var responder:Responder = new Responder(onOK, onErr);
nc.call('AmfTestController.add_book', responder, amf_object);
}
function onOK(res:Object):void
{
trace("目前共有" +res +"本書");
}
function onErr(res:Object):void
{
trace("fail");
}
其實只是把呼叫的部份放到click handler裡,並且在裡面做了一個object,並且在呼叫的時候
nc.call('AmfTestController.add_book', responder, amf_object);
把它當做參數傳出去
接下來,在Rails裡,我們要來加一個add_book這個action,準備接收資料
這裡可以用is_amf來檢查傳進來的是不是AMF
傳進來的參數可用 params[0] 取得
接著執行flash,沒問題的話,當每次按下Add Book按鈕時,它就會把author跟content資料寫入DB
並回傳目前總筆數
以上為展示目的,都沒有加資料的驗證,所以就算空白資料也可以送出
以上是一些個人小小的心得,供大家參考囉
相關網站:
http://blog.rubyamf.org/
http://code.google.com/p/rubyamf/
原始檔下載(fla + rails project):
http://nayumi.myweb.hinet.net/downloads/sample.zip
Oops! 發現最後一篇blog竟然已經是去年的事了!! 是時間過太快還是我太懶了?
最近因為幾個案子在趕著要上線,不久前的OSDC.tw沒辦法全程參加,只好挑自已喜歡的Session參加(ericsk的GAEO比我想像中的還好用)
以前某個我不喜歡的老闆曾跟我說過,做presentation就像表演一樣
近來我自告奮勇的找了一些對flash有興趣的朋友們每週來聚會,每次約2小時,我教大家怎麼來學 ActionScript3.0。沒另外收費(只需各自分擔場地費,我還太嫩,還不到那種敢收學費的等級)
常聽到「這個東西我懂,我只是不會講而已」,但我一直相信,真的懂的人一定是講得出來的;不會講不代表真的不會,只是還沒能完全透徹,某個環節沒學好,講不出來
在台上講話實在是件不容易的事,一來得先克服緊張感,二來得讓自已的腦袋保持清醒。
當然我也沒這麼佛心,開這樣的課當然是有目的:
1. 透過在台上講課,讓自已對AS3更熟悉
2. 訓練自已講話的技巧,練習怎麼掌握台下的反應(可能講太快或一下子講太難)
3. 透過每週準備課程,讓自已不會跟AS3離太遠
越是複雜的技術,要做這種大眾化的教學困難度也越高,像是知名的flash totur Lee Brimelow 用影音的方式來教學,清楚又易懂
最近在路邊牆上貼的一段話:「有困難是能力不夠,有麻煩是方法不對」看來,這條路還相當漫長 :)
Flash在跟Server在交換資料,比較常見的是一般的文字訊息或是XML,我自己在趕時間的時候,會偷懶的隨便echo一個字出來知會flash說server程式已經做完了或是程式執行之後的結果,不趕時間且資料量較多的時候,則會乖乖的用XML。不過,最近開始我比較常用的是AMF跟JSON這兩個方法,其實都還滿方便的,各有其優缺點。
Google新推出的Google Chart API,只要傳幾個簡單的數字進去,它就會產生漂亮的圖表回來(當然PHP的GD或是Imagemagick應該也都行)。在Flash裡面要做圖表也是有方便的元件可以用,不過如果可以透過API以及loadMovie的方式傳回圖片,連元件都省下來了,在製作上就更單純了。
Demo網址:
http://www.eddie.com.tw/FlashLabs/Examples/pieChart/
改變一下數字,圖表就會更著變化,目前似乎是有每天使用次數上的限制,不過對於用在網站管理系統或是拿來做報表系統的圖表,應該是相當夠用的。
Google Chart API其實還有提供更多的圖表可以玩,詳細使用方法請洽http://code.google.com/apis/chart/
這兩天在處理一個案子時遇到一個狀況,困擾了我兩天。例如我先建立了一個menu.swf,並在menu.swf使用Sound類別建立、播放音效如下:
var mySound:Sound = new Sound();
mySound.attachSound("soundClip");
mySound.start();
單獨播放時正常,但當被load到其它swf就發生狀況,聲音出不來
查了一下Adobe網站的資料有發現這一條:
Attached sounds fail in loaded movies
這樣寫著:
This script will function properly except when the SWF containing it is loaded into another movie by aloadMovie action. In this case, the loaded movie loses it’s connection to the linked sound.
解決方法是在建立Sound類別時加個”this“就行了
var mySound:Sound = new Sound(this);
mySound.attachSound("soundClip");
mySound.start();
搞定收工 ![]()
ActionScript3.0裡已經可以完全不用Authoring Tools就能在場景上直接做出按鈕來玩,可以透過「new」的方式來純手工打造,不過老實說是有點麻煩。而且因為我沒很喜歡Flex,又剛好Flash9 Alpha也不能裝,所以只好用flex sdk試玩的,玩起來就又更麻煩一些些了 :)
有測試版可以玩了 [下載頁面]
先來去下載回來裝在測試機上面玩看看
AS 2.0都還沒摸透,3.0就要出來了
真的是跟不上啊 :)