上一篇簡單分享過Progression全組件式的寫法
雖然方便, 但擴充性並不強, 要寫一個專案, 還是需要乖乖來寫程式
玩Progression要先搞懂三個要點:
1. 場景 ScendObject
他是Progression的整個核心架構
你可以想成html, 一個scene就是一頁html
該scene要有什麼元素, 都由這個SceneObject來管理
SceneObject有四個重要的事件:
_onLoad:當該場景被載入時。
_onInit:當該場景被初始化。
_onGoto:當該場景切換到別的場景時。
_onUnload:當該場景被移除時。
SceneObject的生命週期就是走這四個事件。
只有最上一層的主場景_onLoad只會發生一次
_onUnload永遠不會發生, 這個後面會再補充。
2. 可視物件 CastSprite, CastMovieClip
跟一般的Sprite, MovieClip使用起來差不多
但有二個重要的事件。
_onCastAdded:當透過new AddChild 或是 new AddChildAt 加入該物件時, 會發生的事件
_onCastRemoved:當透過new RemoveChild 移除該物件時, 會發生的事件。
3. Command
Progression提供了許多的 Command可以使用
Command Design pattern的好處就是可以依序的執行Command
跑完A, 再跑B , 再跑C,
所以可以很方便的製作單元切換的進退場效果。
像第二點的new AddChild就是 Command的其中一種
一個專案一般只會有一個Progression實體物件。
var prog:Progression= new Progression( 'index', stage, IndexScene );
'index':為該專案的Progression唯一的 Key 值, 只要key值不同, 彼此寫的Progression就不會打架
stage:把stage實體傳入
IndexScene:則是最上一層的 SceneObject, 其他的場景就由這裡開始加入
在這兒範例裡, 做了一個很簡單的架構, 好讓快速上手
首頁場景:
場景上有二個Button,
About:
About的內容可視物件
Contact:
Contact的內容可視物件
其中首頁的場景就是對映剛剛的IndexScene。
先建立Progression
Index.as
同時在IndexScene裡有一個 IndexPage的主畫面。
到這兒先來分析一下
Progression實體被建立, 並goto到第一個場景也就是 IndexScene
當來到 IndexScene 後
就依序發生了_onLoad , _onInit事件
然後我們在_onInit時, 透過new AddChild加入 IndexPage時
接著就會發生 IndexPage裡的 _onCastAdded 事件,
在這兒我們做一個Tweener的進場
當按下about的按鈕時, 要切換到 about場景
就會發生 IndexScene的 _onGogo事件
接著new RemoveChild把 IndexPage移掉
就會發生 IndexPage裡的 _onCastRemoved事件,
在這兒我們也是做一個Tweener的退場
退完場後, 才會進到 AboutScene裡的
_onLoad, _onInit事件。
Progression都是走這樣的模式。
因為是Command模式, 所以一定是一個Command跑完才跑下一個, 不會同時發生
要同時執行多個Command的話也是有這樣的類別。
有任何錯誤的地方, 歡迎請教討論。
SourceCodeDownload
補充:Progression內建的Tween類別是使用Tweener, 我將TweenMax包裝成Command類別,方便在Progression裡使用
請注意TweenMax的類別包喔,
舊版是:gs的package
新版是:com.greensock
雖然方便, 但擴充性並不強, 要寫一個專案, 還是需要乖乖來寫程式
玩Progression要先搞懂三個要點:
1. 場景 ScendObject
他是Progression的整個核心架構
你可以想成html, 一個scene就是一頁html
該scene要有什麼元素, 都由這個SceneObject來管理
SceneObject有四個重要的事件:
_onLoad:當該場景被載入時。
_onInit:當該場景被初始化。
_onGoto:當該場景切換到別的場景時。
_onUnload:當該場景被移除時。
SceneObject的生命週期就是走這四個事件。
只有最上一層的主場景_onLoad只會發生一次
_onUnload永遠不會發生, 這個後面會再補充。
2. 可視物件 CastSprite, CastMovieClip
跟一般的Sprite, MovieClip使用起來差不多
但有二個重要的事件。
_onCastAdded:當透過new AddChild 或是 new AddChildAt 加入該物件時, 會發生的事件
_onCastRemoved:當透過new RemoveChild 移除該物件時, 會發生的事件。
3. Command
Progression提供了許多的 Command可以使用
Command Design pattern的好處就是可以依序的執行Command
跑完A, 再跑B , 再跑C,
所以可以很方便的製作單元切換的進退場效果。
像第二點的new AddChild就是 Command的其中一種
一個專案一般只會有一個Progression實體物件。
var prog:Progression= new Progression( 'index', stage, IndexScene );
'index':為該專案的Progression唯一的 Key 值, 只要key值不同, 彼此寫的Progression就不會打架
stage:把stage實體傳入
IndexScene:則是最上一層的 SceneObject, 其他的場景就由這裡開始加入
在這兒範例裡, 做了一個很簡單的架構, 好讓快速上手
首頁場景:
場景上有二個Button,
About:
About的內容可視物件
Contact:
Contact的內容可視物件
其中首頁的場景就是對映剛剛的IndexScene。
先建立Progression
Index.as
package milkmidi.progression {
import flash.display.*;
import jp.nium.events.DocumentEvent;
import jp.progression.casts.*;
import jp.progression.commands.*;
import jp.progression.core.debug.Verbose;
import jp.progression.events.*;
import jp.progression.loader.*;
import jp.progression.*;
import jp.progression.scenes.*;
import milkmidi.progression.scenes.IndexScene;
public class Index extends CastDocument {
public var prog:Progression;
public function Index() {}
protected override function _onInit():void {
align = StageAlign.TOP_LEFT;
quality = StageQuality.HIGH;
scaleMode = StageScaleMode.NO_SCALE;
//Verbose.enabled = true;
//是否啟用 debug 功能。
//Verbose.filteringCommand();
//debug 功能是否過濾 Command 資訊
prog = new Progression( 'index', stage, IndexScene );
prog.sync = true;
//是否啟用swfAddress功能。
prog.goto( prog.firstSceneId );
//播放第一個場景, 也就是 IndexScene
}
}
}
建立IndexScene, 主場景物件同時在IndexScene裡有一個 IndexPage的主畫面。
package milkmidi.progression.scenes {
import jp.progression.casts.*;
import jp.progression.commands.*;
import jp.progression.events.*;
import jp.progression.loader.*;
import jp.progression.*;
import jp.progression.scenes.*;
import milkmidi.progression.btn.*;
import milkmidi.progression.page.IndexPage;
public class IndexScene extends SceneObject {
public var page:IndexPage = new IndexPage();
public function IndexScene() {
title = "IndexSceneTitle";
//網址的 Title
addScene( new AboutScene('about') );
//加入子場景
}
protected override function _onLoad():void {
//當場景被載入時
//如果是IndexScene(主場景), 就只會被載入一次,
//所以可以把要常駐的物件在這兒加入。
//在這個範例是加入二個按鈕。
var indexButton:IndexButton = new IndexButton();
indexButton.x = 0;
indexButton.y = 400;
progression.container.addChild( indexButton );
var _aboutBtn:AboutButton = new AboutButton();
_aboutBtn.x = 100;
_aboutBtn.y = 400;
progression.container.addChild(_aboutBtn);
addCommand(
new Trace(this + "._onLoad()")
);
}
protected override function _onInit():void {
//當場景被初始化時
//該函式會接在_onLoad後發生
//除非是直接呼叫該場景的子場景
//ex: #/about/aboutchild/
//那_onInit就不會發生。
addCommand(
new Trace(this + "._onInit()"),
new AddChild( progression.container, page )
);
}
protected override function _onGoto():void {
//當場景離開時
addCommand(
new Trace(this + "._onGoto()"),
new RemoveChild( progression.container, page )
);
}
protected override function _onUnload():void {
//當場景移除時
addCommand(
new Trace(this + "._onUnload()")
);
}
override public function toString():String {
return "[" + name + "Scene]";
}
}
}
package milkmidi.progression.page {
import flash.text.TextField;
import flash.text.TextFormat;
import jp.progression.casts.*;
import jp.progression.commands.*;
import jp.progression.events.*;
import jp.progression.loader.*;
import jp.progression.*;
import jp.progression.scenes.*;
public class IndexPage extends CastSprite {
public var txt:TextField;
public function IndexPage( initObject:Object = null ) {
super( initObject );
//這兒只是做一個文字。
txt = new TextField();
txt.width = 400;
txt.text = "IndexPage";
txt.setTextFormat( new TextFormat("Arial", 60));
txt.mouseEnabled = false;
addChild( txt );
}
protected override function _onCastAdded():void {
//當透過new AddChild 或是 new AddChildAt 加入該物件時, 會發生的事件。
//直接使用addChild的話是不會發生該事件的喔。
txt.x = -400;
//透過 Command, 可以在這兒加入進場的效果。
addCommand(
new Trace(this + "_onCastAdded()"),
new DoTweener( txt, {
x:0,
time:1
} )
);
}
protected override function _onCastRemoved():void {
//當透過new RemoveChild 移除該物件時, 會發生的事件。
//直接使用DisplayObjectContent的removeChild的話是不會發生該事件的喔。
//在這兒就可以加入退場的效果。
addCommand(
new Trace(this + "_onCastRemoved()"),
new DoTweener( txt, {
x:-400,
time:1
} )
);
}
override public function toString():String {
return "IndexPage";
}
}
}
到這兒先來分析一下
Progression實體被建立, 並goto到第一個場景也就是 IndexScene
當來到 IndexScene 後
就依序發生了_onLoad , _onInit事件
然後我們在_onInit時, 透過new AddChild加入 IndexPage時
接著就會發生 IndexPage裡的 _onCastAdded 事件,
在這兒我們做一個Tweener的進場
當按下about的按鈕時, 要切換到 about場景
就會發生 IndexScene的 _onGogo事件
接著new RemoveChild把 IndexPage移掉
就會發生 IndexPage裡的 _onCastRemoved事件,
在這兒我們也是做一個Tweener的退場
退完場後, 才會進到 AboutScene裡的
_onLoad, _onInit事件。
Progression都是走這樣的模式。
因為是Command模式, 所以一定是一個Command跑完才跑下一個, 不會同時發生
要同時執行多個Command的話也是有這樣的類別。
有任何錯誤的地方, 歡迎請教討論。
SourceCodeDownload
補充:Progression內建的Tween類別是使用Tweener, 我將TweenMax包裝成Command類別,方便在Progression裡使用
請注意TweenMax的類別包喔,
舊版是:gs的package
新版是:com.greensock
package milkmidi.progression.commands.display {
import jp.progression.core.commands.Command;
import gs.TweenMax;
import gs.easing.*;
import gs.events.TweenEvent;
public class DoTweenMax extends Command {
private var _target :Object;
private var _parameters :Object;
private var _tweenMax :TweenMax;
private var _duration :Number;
public function DoTweenMax( pTarget:Object, pDuration:Number, pParameters:Object, pInitObject:Object = null ) {
_target = pTarget;
_duration = pDuration;
_parameters = pParameters;
super( _execute, _interrupt, pInitObject );
}
private function _execute():void {
timeOut = Math.max( timeOut, _duration + 5000 );
_tweenMax = new TweenMax( _target, _duration, _parameters);
_tweenMax.addEventListener(TweenEvent.COMPLETE , _complete, false, int.MAX_VALUE, true);
if ( _tweenMax ) { return; }
executeComplete();
}
private function _complete( e:TweenEvent ):void {
_tweenMax.removeEventListener(TweenEvent.COMPLETE , _complete, false);
executeComplete();
}
override public function executeComplete():void {
super.executeComplete();
_tweenMax = null;
}
private function _interrupt():void {
//trace("_interrupt");
_tweenMax.clear();
interruptComplete();
}
public override function clone():Command {
return new DoTweenMax( _target, _duration , _parameters );
}
}
}
留言
這種的是好東西阿
不過命令模式是Progression最大的特色,
不知道奶綠老師能不能夠多分享這方面的心得?
請問什麼是CS4裡的flash.swc copy到專案呢?
你是想要在CS4使用Progression嗎
你可以安裝他的類別檔
或是安裝他的swc檔
http://progression.jp/download/3.1.62/Progression3-swc.zip
這兒可以下載Progression3的swc檔
所以沒發現到他有把fl.transitions:Tween包裝在裡面了,
為了要用dotween,又只想使用sdk發布,
還特地把flashCS4中的flash.swc copy到專案...
用progression.swc就不用多此一舉了~
並沒有fl.裡的Class,
但用Progression.swc他就有包裝在裡面
我也都是用Flex SDK再發怖專案
Flash只是用來做元件
把'index'換一個名稱
這樣就不會衝突了
小弟習慣使用 TweenLite 來寫~
為什麼一直出錯???
是不是要先把 tweener 刪掉還是.....
我用 progression3.swc 會出錯耶~
我把檔案放在
src\libs\com\greensock
tween 效果都有出來~可以正常使用~
但就是會有錯誤訊息...
請問奶大有這類情況嗎?
感謝感謝~~~
你出現的錯誤訊息是什麼呢?
你上線我再傳完整的as檔類別給你
Error: Error #9028: Specified the object does not correspond.
Error: Error #9028: Specified the object does not correspond.
我在創見專案的時候不要用 swc 輸出~
就一切正常了...
Progression 真的太好用了!!!
靈活、方便、快速!~~真是一大福音!!!
感謝奶大~這麼多篇教學~~小弟沒齒難忘~以身相許~~~....誰受的了?
再次感謝奶綠~
在 addCommand 裡不能用 TweenLite 耶...
真是又讓我陷入一陣錯愕......
不好意思~一直麻煩您~~~
,我貼在上方,請享用
但您的程式碼運行似乎有兩個問題~請奶大幫幫忙~
1.在您的程式碼中我看已經有加入 import com.greensock.easing.*; 但沒有發揮作用~我必須在各頁面.as 還是要在 import 一次才有作用^^....
2._tweenMax.clear(); 這句也會造成錯誤!
以上是小地使用測試心得~感謝奶綠大~感謝~~
而每一個as都要import該類別是正常的
import是針該對隻as而不是針對整個flash應用程式喔
感謝奶綠大的教學!~~~感恩!~~
全 class 寫動態定位 onResize
將語法寫在 index.as 只能定位 index入場的物件,請問我要怎麼動態定位 IndexPage 其他頁面的物件???
我換了好多種寫法...
都無法動態定位...
感謝奶綠老師解答!.... 一鞠躬!
馬克提供了這個http://blog.cuegraphix.com/?p=68
但我現在手邊沒檔案,明天再來繼續試了
感謝