上一篇簡單分享過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
但我現在手邊沒檔案,明天再來繼續試了
感謝