新增類別
再沿用上一個範例。我們製作一個CastNaviButton的類別繼承CastButton,放在myproject.index底下。打開index.fla,將IndexButton等Button元件的Base Class改成myproject.index.CastNaviButton。
判斷狀態CastButton.state,以及狀態改變事件CastMouseEvent.CAST_STATE_CHANGE
CastButton有一個state屬性,值是int,用來識別現在CastButton的狀態。值所代表的意義則是參考CastButtonState這個類別:
| 常數名稱 | 值 | 說明 |
| CHILD | 1 | 現在Scene是Button設定Scene的Child。 |
| CURRENT | 2 | 現在Scene剛好是Button設定Scene。 |
| DISABLE | 0 | 無效的狀態。沒有指定SceneId也沒指定href。 |
| NEUTRAL | 4 | 一般狀態。 |
| PARENT | 3 | 現在Scene是Button設定Scene的Parent。 |
群組CastButton.group,以及依群組尋找實體getInstancesByGroup
CastButton可以自由設定group,內容是字串。而jp.progression.casts這個package底下有個getInstancesByGroup function,可以把相同group的實體搜出來。如果導覽列跟場景上都有個要前往Product Scene的Button,那我們可以將這兩個Button的group都設定為"productBtnGroup",然後mouse over與mouse out的時候經由getInstancesByGroup 把同樣group的實體回傳回來,然後讓它們都執行mouse over與mouse out該有的動作就可以了。
加上偵聽MouseEvent.CLICK事件
既然CastButton沒有CLICK事件,我們就偵聽最原始的MouseEvent.CLICK吧。然後一樣順便仿照CastButton,加上atCastClick與onCastClick,讓我們可以複寫或指定屬性的方式來加上處理常式。
加入enableAtChildScene做更多判斷
還有一個常見的情形,P2Scene是ProductScene的Child Scene,很多時候我們希望進入P2Scene的時候,導覽列的ProductButton也跟P2Button一樣處於Highlight且不可點的狀態。但像回首頁用的IndexButton就不能這樣做,因為所有的Scene都是IndexScene的Child Scene,這樣會讓IndexButton永遠不能點。這個參數我們讓它預設是false,而IndexButton再去設為true就可以了。
綜合以上幾點,我們就直接把CastNaviButton的原始碼貼出來:
package myproject.index{
import flash.events.MouseEvent;
import jp.progression.casts.CastButton;
import jp.progression.casts.CastButtonState;
import jp.progression.casts.getInstancesByGroup;
import jp.progression.events.CastMouseEvent;
import jp.progression.commands.tweens.DoTweenFrame;
/**
* ...
* @author Gray Liao
*/
public class CastNaviButton extends CastButton
{
private var _enableAtChildScene:Boolean = false;
public function get enableAtChildScene():Boolean { return _enableAtChildScene; }
public function set enableAtChildScene( value:Boolean ):void { _enableAtChildScene = value; }
public function CastNaviButton(initObject:Object = null){
super(initObject);
addEventListener(CastMouseEvent.CAST_STATE_CHANGE, _stateChange);
addEventListener(MouseEvent.CLICK, _click);
stop();
}
override protected function atCastRollOver():void
{
if(group != null)
{
gotoOverByGroup(group);
}else{
onGroupOverHandler();
}
}
override protected function atCastRollOut():void
{
if(group != null)
{
gotoUpByGroup(group);
}else{
onGroupOutHandler();
}
}
protected function gotoOverByGroup(group:String):void
{
var obj:CastNaviButton;
var groupObj:* = getInstancesByGroup(group);
for each (obj in groupObj){
obj.onGroupOverHandler();
}
}
protected function gotoUpByGroup(group:String):void
{
var obj:CastNaviButton;
var groupObj:* = getInstancesByGroup(group);
for each (obj in groupObj){
obj.onGroupOutHandler();
}
}
public function onGroupOverHandler():void
{
gotoAndStop("stop");
}
public function onGroupOutHandler():void
{
gotoAndStop("in");
}
private function _stateChange(e:CastMouseEvent):void
{
atStateChange();
if (_onStateChange != null)
{
_onStateChange();
}
}
protected function atStateChange():void
{
switch(state)
{
case CastButtonState.CHILD:
if (_enableAtChildScene)
{
buttonEnable();
}else {
buttonDisable();
}
break;
case CastButtonState.CURRENT:
buttonDisable();
break;
default:
buttonEnable();
break;
}
}
public function get onStateChange():Function { return _onStateChange; }
public function set onStateChange( value:Function ):void { _onStateChange = value; }
private var _onStateChange:Function;
private function _click(e:MouseEvent):void
{
atCastClick();
if (_onCastClick != null)
{
_onCastClick();
}
}
protected function atCastClick():void
{
buttonDisable();
}
public function get onCastClick():Function { return _onCastClick; }
public function set onCastClick( value:Function ):void { _onCastClick = value; }
private var _onCastClick:Function;
protected function buttonEnable():void
{
mouseEventEnabled = true;
useHandCursor = true;
gotoAndStop("in");
}
protected function buttonDisable():void
{
mouseEventEnabled = false;
useHandCursor = false;
gotoAndStop("stop");
}
}
}
程式碼很單純實現上面幾個問題的解法,就不多做解釋了。修改Navi
在Navi的建構式中,在設定Button的迴圈跑完後,多一行設定:
index_mc.enableAtChildScene = true;而在setButton()這個function裡面把設定onCastRollOver與onCastRollOut的部分拿掉,因為在CastNaviButton裡面我們已經複寫atCastRollOver與atCastRollOut了。
測試與下載
最後來看看結果:請按此。
下載範例:請按此。
到此為止,應該一般網頁架構的問題都解決了,剩下一些小問題,例如:
1.現在元件都是在加入舞台時去計算該在的位置,但最好加上Satge Resize的處理,這部分因為在progression裡面stage很好抓,要加偵聽不難,況且可能大部份人都有對位的類別或組件了,就不花篇幅去介紹。
2.有些選單在首頁時,"回首頁"的Button是不在的,等到進入內頁時才出現。但這其實隨著場景去控制Navi的兩種狀態就可以了,其狀況也是沒辦法都涵蓋的了,所以就先留著了。
所以這一系列的文章就告一段落了。Progression其實還有很多有趣的東西,例如Effect,各種特殊的Cast,還有Resource功能,甚至可以在背景下載其他內容。這些等有機會再來介紹啦。
上一篇文章:Progression 4 歡樂開發Flash網站 ( 4 ) — 分割各場景元件庫
你寫得好詳細!! 推推推
回覆刪除因為每個專案花在這些工作上的時間越少越好,所以一次整理清楚,之後就可以專心在比較有趣的程式碼上面啦
回覆刪除從安裝、新增專案到實際範例,一系列的文章閱讀完對Progression 也有了基本的概念,非常感謝 : )
回覆刪除看完有種醍醐灌頂的爽快,太感謝啦!!~~(膜拜~
回覆刪除這篇好讚!感謝gray分享~~~~~
回覆刪除好文,不推不可。按個讚!
回覆刪除感覺progression來做網站反而複雜了。
回覆刪除To 迷茫feel:
回覆刪除我覺得是現在網站的需求比以前複雜多了
如果網站沒有很多進退場順序需要安排,不需要串swfAddress,那麼當然就不需要拿progression來用囉
太。強。悍
回覆刪除