2010年1月20日 星期三

Coverflow無限loop版

學生問到怎麼將Coverflow改成無限loop的版本
概念上都是一樣的,只要更改移動的公式即可,加上if else來判斷座標位子即可。
Thumbnail - Click me

SourceCodeDownload

2010年1月17日 星期日

FlashDevelopPlugin

FlashDevelop是一套超好用的 ActionScript 程式碼編輯器
而且是免費的軟體喔,
來介紹幾個奶小茶覺得還不錯的外掛
FDFlexFormatter v0.2
是一個可以快速將你的程式碼自動排排站好的外掛, 類似Flash的 autoFormat
亂的程式碼

使用FDFlexFormatter整理過後的程式碼


Duplicate
快速重製程式碼, 以往打了addEventListener(MouseEvent.ROLL_OVER , rollOverHandler);
通常下一行會再偵聽ROLL_OUT事件。
以前最快的方法是,按Ctrl+ D, 先整排復製, 然後再去改成ROLL_OUT
安裝好該外掛,按下Ctrl + Alt + D,就會自動幫你整排復製, 然後將ROLL_OVER改成ROLL_OUT
超省時的啦, 當然關鍵的文字可以自已新增修改
還有Ctrl + Alt + S, 每按一下就能自動切換
addEventListener換成removeListener
或是public internal protected privte自動切換
而Ctrl + Alt + Shift + D, 遇到數字型時,就會自動幫你加一行, 並將數字遞增

Highlightselection
當選取一個文字時, 該文件檔只要有一樣的文字, 會自動幫你出現底色, 方便預視
可以檢查是否打錯字

SWCExport
安裝好後, 在上方工具列就會出現新的Icon, 按下後就能將類別直接包裝成.swc

http://code.google.com/p/flashdevelopjp/
安裝好後, 在上方工具列會多出一個日文選項,
前二個我不知道是做什麼用的
Always Compile設定:只要按下Alt +A ,就才自動幫你把目前開啟的.as設定成Always Compile,
還可以到選項裡更改設定,就可以直接發怖。


Vizzy Flash Tracer

這一個不算是FD的外掛, 有點像是FireFox的flash tracer,
只是他是單一執行軟體, 不用加裝在任何Brwoser上即可使用
當然flashDevelop的trace資訊他也是抓的到

FlexDbg
FlashDevelop也能使用.net的中斷點功能喔, 這樣就可以一步一步的debug


2010年1月14日 星期四

AS3 utf8 轉 big5編碼

AS3預設的編碼即是utf-8, 但有時html的編碼不是我們能控製的
好比html是big5,
在flash裡只要使用System.useCodePage = true;
即可讓flash的編碼和html相同,
但問題來了, 假設現在遠端主機接受的編碼是big-5
你有二個網站分別用big5和utf8製作, 光轉編碼可能就會搞死,
好在有好心人士己編整理好了, 感謝馬克提供的資訊
http://www.mr-fu.net/2009/02/url-encoding-in-actionscript3-utf-8.html
原理是透過ByteArry來處理。

2010年1月9日 星期六

CoverFlow另一種表現手法

有學生問到如何製作這樣的3D效果
http://www.movie-motel.com/
更改了一下書裡的Appendix_A CoverFlowCS4.as
當然也可以用PV3D來製作, 原理上差不多
只要更改一下公式即可:
和本來的Coverflow效果一樣,
會有三種情況, 左邊,中間、右邊
只要更改左邊的公式, z軸改成負的即可。
Thumbnail - Click me

package {
import flash.display.*;
import flash.events.*; 
import flash.net.*;
import flash.net.URLRequest;
import caurina.transitions.Tweener; 
public class CoverFlowCS4_3 extends Sprite {   
private var itemOfNumber  :int = 9;//物件數量
private var currentPlaneIndex :Number = 0;//目前圖片的索引值
private var planeAngle   :Number = 48;   //角度
private var planeSeparation  :Number = 150;  //左右二邊Plane與Plane的間距。
private var planeOffset   :Number = 100;  //目前所選擇的Plane其左右的間距。
private var selectPlaneY  :Number = -0;  //目前所選擇Plane的y值
private var selectPlaneZ  :Number = -510; //目前所選擇Plane的z值
private var perZ    :int = 250;
private var container   :Sprite;
private var sortArray   :Array = [];//排序用的陣列
public function CoverFlowCS4_3() {
addEventListener(Event.ADDED_TO_STAGE, _addedToStageHandler);   
}    
private function _addedToStageHandler(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, _addedToStageHandler);
initObject();   
}
private function initObject():void {
container = new Sprite();
//建構物件,其類別為Sprite。
container.x = stage.stageWidth / 2;
container.y = stage.stageHeight / 2;
//對個場景的正中間。
container.z = 500;
//Sprite繼承DisplayObject, 一樣擁有3D屬性。
//z軸為正500,就是往後移動。
//container.rotationX = 5;
//以x軸為軸心做旋轉。
this.addChild(container);
//加入至目前的容器。
for (var i:int = 0 ; i < itemOfNumber; i++){
var _mc:MovieClip = new ItemMC();
//宣告_mc變數,型別為MovieClip,建構ItemMC類別,來源是元件庫設定的類別名稱。
var _ldr:Loader = new Loader();
//建構Loader類別。
_ldr.load(new URLRequest("images/" + i + ".jpg"));
//載入圖檔。      
_ldr.x = -127;
_ldr.y = -120;
_mc.addChild(_ldr);
//將Loader加入至_mc物件裡。
_mc.id = i;
_mc.extra = { };
//直定id變數。
_mc.z = i * -20;
//修改z軸屬性。
_mc.name = "item" + i;
//實體名稱。
_mc.buttonMode = true;
//開啟按鈕模式。
_mc.addEventListener(MouseEvent.ROLL_OVER, onEventRollOver);
_mc.addEventListener(MouseEvent.ROLL_OUT, onEventRollOut);
_mc.addEventListener(MouseEvent.CLICK, onClick);
//偵聽滑鼠事件。
container.addChild(_mc);
//將_mc物件加入至container裡。
sortArray.push(_mc);
}
stage.addEventListener( MouseEvent.MOUSE_WHEEL, onEventMouseWheel);
//偵聽滾輪事件。
shiftToItem( int(itemOfNumber * .5) );   
//執行shiftToItem函式。
}

private function onEventRollOver(e:MouseEvent):void {
var _target:MovieClip = e.currentTarget as MovieClip;
_target.gotoAndPlay("over");
if (_target.id > currentPlaneIndex)   
Tweener.addTween( _target , 
{
x   :_target.extra.x + 50,
z   :_target.extra.z - 100,
time  :1,
transition :"easeInOutExpo"
});   
}

private function onEventRollOut(e:MouseEvent):void {
var _target:MovieClip = e.currentTarget as MovieClip;
_target.gotoAndPlay("out");
if (_target.id > currentPlaneIndex)   
Tweener.addTween( _target , 
{
x   :_target.extra.x,
z   :_target.extra.z,
time  :1,
transition :"easeInOutExpo"
});   
} 
public function shiftToItem(p_id:int):void{
if (p_id == currentPlaneIndex) {  
//navigateToURL(new URLRequest(HREF_ARR[p_id]), "_self");    
return;  
}  
currentPlaneIndex = p_id;   
var _tweenObj:Object;
//用for回圈,一次更改所有plane的屬性。
for (var i:int = 0; i < itemOfNumber; i++){
var _mc :MovieClip = container.getChildByName("item" + i) as MovieClip;
//container是Sprite類別,可以使用getChildByName的方法得到其子系物件。    
//型別不同,所以要轉換。
var dis  :int = i - p_id;
var _absDis :int = Math.abs(dis);
//算出目前回圈值與新值的差。
if (i == p_id) {
//如果目前回圈值等於新值
//表示該plane為正中間顯示。
_tweenObj =
{
x   :0,
y   :selectPlaneY,
z   :selectPlaneZ,     
rotationY :0,
onUpdate    :sortChildren
//數值更新時, 不斷的執行sortChildren函式。
};
//把值寫入到_tweenObj物件裡。
} else if (i < p_id) {
//如果回圈值小於新值
//表示該plane在左邊。
_tweenObj =
{
x   :dis * planeSeparation - planeOffset - 200,
y   :0,
z   :dis * perZ + selectPlaneZ,
rotationY :planeAngle
};

} else  {
//plane在右邊。
_tweenObj =
{
x   :dis * planeSeparation  + planeOffset,
y   :0,
z   :_absDis * perZ,     
rotationY :planeAngle
};
}
_mc.extra.x = _tweenObj.x;
_mc.extra.z = _tweenObj.z;
_tweenObj.time = 1;
Tweener.addTween(_mc, _tweenObj);
//使用Tweener移動物件。
}
}  
private function onClick(e:MouseEvent):void{
var _id:int = e.currentTarget.id;
shiftToItem(_id);
//把該值傳進shiftToItem執行。
}
private function onEventMouseWheel(e:MouseEvent):void {
//MouseEvent類別下, delta可以得到滑鼠滾輪的值
if (e.delta < 0)  {
moveRight();
}else {
moveLeft();
}
}
public function moveLeft():void {
if (currentPlaneIndex > 0) {
//如果目前plane的索引值大於0的話
shiftToItem(currentPlaneIndex - 1);
}
}
public function moveRight():void{
if (currentPlaneIndex < itemOfNumber -1) {
//如果目前plane的索引值小於總數量扣一
shiftToItem(currentPlaneIndex + 1);
}
}
public function sortChildren():void {   
sortArray.sortOn("z", Array.NUMERIC | Array.DESCENDING);
//使用陣列的排序方法,依參數p_criteria,以數字型態遞減排序。   
for (var i:int =  0; i< sortArray.length; i++) {
var _child:MovieClip = sortArray[i] as MovieClip;    
container.setChildIndex( _child, i );
//重新指定深度。    
}  
}
}
}

需搭配CoverFlowCS4.fla一起發怖才行喔

2010年1月5日 星期二

facebookApp抓取相片集

最近一定都要來facebook一下,
今天來介紹如何在網站裡, 得到目前使用者facebook裡的相片集
1.請申app, 得到API_KEY和SECRET_KEY
關於facebook app申請與設定, 可以參考
http://milkmidi.blogspot.com/2009/10/facebook-app.html
2.下載facebook flash api類別:
http://code.google.com/p/facebook-actionscript-api/
3.說明一下原理
使用者在你的應用程式裡點選登入後, 會自動開啟connect的頁面, 讓使用者同意你的app取存個人資訊
登入成功後, 就可以開始要資訊
相片集的話, 會有二個部份
一個是Albums(就是相本, 使用GetAlbums類別)
一個是Photos(就是相本裡的相片, 使用GetPhotos類別, 要帶入Albums裡的id值)
二者呼叫fb後回傳的結果都是一個Collection
在這兒使用Flex來練習, 當然用Flash原理也是一樣的




<![CDATA[
import com.facebook.commands.data.*;   
import com.facebook.commands.friends.GetFriends;
import com.facebook.data.friends.GetFriendsData;
import com.facebook.data.photos.AlbumData;
import com.facebook.data.photos.PhotoData;
import com.facebook.data.users.FacebookUserCollection;      
import com.facebook.Facebook;
import com.facebook.events.FacebookEvent;
import com.facebook.net.FacebookCall;
import com.facebook.data.photos.*;   
import com.facebook.commands.photos.*;   
import com.facebook.utils.FacebookSessionUtil;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.utils.ObjectUtil;
private static const API_KEY  :String = "365c040dcb9fc14260ceb5234107e1e5";
private static const SECRET_KEY :String = "2c7e80f2551c4593ba02d2c2c8e92498"; 
private var fbook  :Facebook;
private var fbSession :FacebookSessionUtil;   

[Bindable] private var facebookPhotoAlbums :ArrayCollection; 
[Bindable] private var facebookPhotos  :ArrayCollection;   

private function appComplete():void {
fbSession = new FacebookSessionUtil( API_KEY , SECRET_KEY, loaderInfo);                   
fbSession.addEventListener(FacebookEvent.WAITING_FOR_LOGIN, _waitingForLoginHandler); 
//等待使用者點選同意時。
fbSession.addEventListener(FacebookEvent.CONNECT, _fbfbSessionConnectHandler);   
//當使用者點選同意connect後。
}         
private function _waitingForLoginHandler(e:FacebookEvent):void {
var _alert:Alert = Alert.show("Click OK when you've logged in", "Logging into Facebook");
//跳一個Alert;
status.text = "Connecting";
_alert.addEventListener(Event.CLOSE, doClose);    
}
private function doClose(e:Event):void {   
fbSession.validateLogin();         
//關掉alert時,去驗證是否登入成功。
}        
private function _fbfbSessionConnectHandler(e:FacebookEvent):void {
status.text = "Facebook API Ready"; 
fbook = fbSession.facebook;    
//is_connected屬性即可得知是否登入成功。
if (fbook.is_connected) 
getPhotoAlbums();    
}      
private function getPhotoAlbums():void {    
//得到相本集
var _call:FacebookCall = fbook.post(new GetAlbums(fbook.uid));    
_call.addEventListener(FacebookEvent.COMPLETE, _getAlbumsHandler);          
}
private function _getAlbumsHandler(e:FacebookEvent):void {
var _getAlbumsData:GetAlbumsData = e.data as GetAlbumsData;    
if (!_getAlbumsData || e.error){ 
status.text = "Error";
return;
}       
facebookPhotoAlbums = new ArrayCollection();                  
for (var i:int = 0; i < _getAlbumsData.albumCollection.length; i++) {
var _obj:AlbumData = _getAlbumsData.albumCollection.getItemAt(i) as AlbumData;     
facebookPhotoAlbums.addItem(_obj);        
}   
}   
private function showSelectedAlbumHandler(e:Event):void {  
//得到相本
var _selectedAlbumID:String = e.currentTarget.selectedItem.aid;
trace("selectedAlbumID:" + _selectedAlbumID);    
var _call:FacebookCall = fbook.post(new GetPhotos('', _selectedAlbumID));
_call.addEventListener(FacebookEvent.COMPLETE, _getPhotosHandler);
}
private function _getPhotosHandler(e:FacebookEvent):void {
var _getPhotosData :GetPhotosData = e.data as GetPhotosData;    
if (!_getPhotosData || e.error){ 
status.text = "Error";
return;
}              
facebookPhotos = new ArrayCollection();      
for (var i:int = 0; i < _getPhotosData.photoCollection.length; i++) {
var _obj:PhotoData = _getPhotosData.photoCollection.getItemAt(i) as PhotoData;              
facebookPhotos.addItem(_obj); 
}
}   
]]>