跳到主要內容

Progression3 tutorial part2

上一篇簡單分享過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
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 );   
}
}
}

留言

Unknown寫道…
感激老師,

這種的是好東西阿
烤焦餅乾寫道…
把cs4裡面的flash.swc copy到專案裡後,還能夠不透過fla直接使用progression裡用再命令模式中的Dotween.
不過命令模式是Progression最大的特色,
不知道奶綠老師能不能夠多分享這方面的心得?
milkmidi寫道…
hi,
請問什麼是CS4裡的flash.swc copy到專案呢?
你是想要在CS4使用Progression嗎
你可以安裝他的類別檔
或是安裝他的swc檔
http://progression.jp/download/3.1.62/Progression3-swc.zip
這兒可以下載Progression3的swc檔
烤焦餅乾寫道…
作者已經移除這則留言。
烤焦餅乾寫道…
因為我沒使用swc,直接使用類別目錄檔,
所以沒發現到他有把fl.transitions:Tween包裝在裡面了,

為了要用dotween,又只想使用sdk發布,
還特地把flashCS4中的flash.swc copy到專案...

用progression.swc就不用多此一舉了~
milkmidi寫道…
是的, 如果用他的.as檔
並沒有fl.裡的Class,
但用Progression.swc他就有包裝在裡面
我也都是用Flex SDK再發怖專案
Flash只是用來做元件
寫道…
老師你好,請問一下,如果我在一個Progression專案中載入一個swf,這個swf也是一個Progression專案的fla,載入後,原本場景上的物件出現感應區被擋住的問題,似乎是兩個Progression class互相干擾的問題,請問有甚麼解決辦法嗎?
milkmidi寫道…
prog = new Progression( 'index', stage, IndexScene );
把'index'換一個名稱
這樣就不會衝突了
匿名表示…
真的好好用!超感謝老師在課堂上實際帶我們操作!
milkmidi寫道…
不客氣,加油
Midi表示…
請問奶老大~
小弟習慣使用 TweenLite 來寫~
為什麼一直出錯???

是不是要先把 tweener 刪掉還是.....
我用 progression3.swc 會出錯耶~

我把檔案放在
src\libs\com\greensock
tween 效果都有出來~可以正常使用~
但就是會有錯誤訊息...

請問奶大有這類情況嗎?

感謝感謝~~~
milkmidi寫道…
Tweener和TweenLite可以共用
你出現的錯誤訊息是什麼呢?
HARDMOUSE寫道…
I can't find anywhere has actionscript. Only found a "/src/libs/Progression3.swc"? How do I edit *.as in progression?
milkmidi寫道…
我的demo是用FlashDevelop+swc發怖
你上線我再傳完整的as檔類別給你
Midi表示…
奶老大~我只要使用 TweenLite 就回出現以下錯誤?~ 感謝奶大幫忙解惑....

Error: Error #9028: Specified the object does not correspond.
Midi表示…
解決問題!會發生以下現象...
Error: Error #9028: Specified the object does not correspond.

我在創見專案的時候不要用 swc 輸出~
就一切正常了...

Progression 真的太好用了!!!
靈活、方便、快速!~~真是一大福音!!!

感謝奶大~這麼多篇教學~~小弟沒齒難忘~以身相許~~~....誰受的了?

再次感謝奶綠~
Midi表示…
請問一下奶綠大~

在 addCommand 裡不能用 TweenLite 耶...

真是又讓我陷入一陣錯愕......

不好意思~一直麻煩您~~~
milkmidi寫道…
我有將TweenMax寫成Progression Command
,我貼在上方,請享用
Midi表示…
首先瘋狂感激 奶綠大 分享 TweenMax Command !!!大鼓掌~~~

但您的程式碼運行似乎有兩個問題~請奶大幫幫忙~

1.在您的程式碼中我看已經有加入 import com.greensock.easing.*; 但沒有發揮作用~我必須在各頁面.as 還是要在 import 一次才有作用^^....

2._tweenMax.clear(); 這句也會造成錯誤!

以上是小地使用測試心得~感謝奶綠大~感謝~~
milkmidi寫道…
不好意思,因為我是使用舊版本的gs.TweenMax來製作,沒注意到新版的TweenMax會有這樣問題,謝謝你提供的資訊。
而每一個as都要import該類別是正常的
import是針該對隻as而不是針對整個flash應用程式喔
Midi表示…
沒錯~每個頁面可以依照要使用 easing 獨立崁入~對檔案大小也有幫助!!!

感謝奶綠大的教學!~~~感恩!~~
Midi表示…
請問奶綠老師~入門問題~(我很菜~)
全 class 寫動態定位 onResize
將語法寫在 index.as 只能定位 index入場的物件,請問我要怎麼動態定位 IndexPage 其他頁面的物件???

我換了好多種寫法...
都無法動態定位...

感謝奶綠老師解答!.... 一鞠躬!
milkmidi寫道…
每個可視物件,自已去偵聽stage的resize事件就可以了
Gray Liao寫道…
Dear 奶綠,請問一下,一般我們使用swfobject.embedSWF嵌入flash,只要設定一個attributes.id給他,js就可以呼叫到flash裡的function(透過ExternalInterface.addCallback),但透過progression.embedSWF,我好像怎麼設定都沒用,照理講它應該只是把這些參數再丟給swfobject.embedSWF才對呀?不知道你有沒有遇過這樣的問題?
milkmidi寫道…
我想一下,應該是正常才對,我之前也有用Progression+FBConnect,也是js as互call,你是用幾版的Progression呢,3還是4呢,我來查一下
Gray Liao寫道…
我是用3.1版的
馬克提供了這個http://blog.cuegraphix.com/?p=68
但我現在手邊沒檔案,明天再來繼續試了
感謝
milkmidi寫道…
我試了一下是可以的呀,不然你上線Q我,我把我試的檔案給你參看一下

這個網誌中的熱門文章

奶綠茶新書上市_密技公怖_程式碼下載

奶綠茶第一本 Flash 書籍上市啦 博客來書籍館 Flash 3D 特效宅急便 - 商業範例隨學隨 把我對 Flash 的研究與熱愛, 全寫在其中 本書的前幾章, 特別安排 ActionScript3.0 的許多範例 好讓你一步步瞭解 as2 和 as3 的差別 再安排製作動畫不可缺少的 Tweener 類別和一些常用的數學動畫公式 最後當然就來到本書的重點 PV3D 啦 從 PV3D 的原理, 基本架構一點一點的介紹 再透過許多實用的範例, 從中瞭解 PV3D 製作的小技巧 有任何書籍相關的問題, 也請不吝指教 感謝一路走來, 幫助過我的前輩們, 邦邦、Ticore、神魂、Maso、Erin 旗標出版社 小編 Bready 米蘭數位所有夥伴 米蘭數位ActionScript Team:Jason,Ash,Mark 本書大鋼: 1.ActionScript3.0概論 分析AS3的概念與語法, 從基本的滑鼠事件、外部載入、氣泡事件介紹起 適合熟悉AS2, 想轉戰AS3的人員。 2.程式碼製作動畫 使用簡單的數學公式, 套用到程式裡, 脫離死版的影格動畫。 3.製作動畫的好夥伴:Tweener 除了套用數學公式外, Tweener類別也能加速我們開發出更多的動畫效果, 不需辛辛苦苦的找公式。 4.自定類別 AS3的精神, 是在於強大的物件導向, 當然也要熟悉類別的寫法與使用。 5.Flash3D - Papervison3D 如果在Flash玩轉3D效果, PV3D是最好學, 最快上手的3D Flash Engine, 從簡單的3D概念, PV3D類別, 事件等。 6 漫天飛舞的Paper3DWorld效果 7 迷你旋轉木馬式秀圖效果 8 最經典! CoverFlow 圖像展示效果 9 天旋地轉 TiltViewer效果 10 FlatWall3D電視牆效果 11 經典旋轉木馬 Carousel3D 秀圖效果 12 光源材質展示與簡易型的方塊彈跳效果 13 載入外部3D模型與動畫 14 超立體旋轉九宮格 Box3DWorld 15 空間感與透明感兼具的 SpaceGallery 16 螺旋式 SpiralCarouse 影像展示 17 Flash10 3D功能 18 Flash效

奶綠茶photoGalleryV3.5

奶小茶的photoGalleryV3.5原始檔 2007/12/30 更新小Bug,請重新下載 線上Demo: http://milkmidi.com/photogallery/galleryv3.html 1.支援SWFAddress,讓FLASH可以有上一頁下一頁和每張獨立網址的功能 2.圖片路徑圖說經由XML來設定 3.背景依據顯示圖片,自動變化成最接近的顏色 4.非商業用途,歡迎使用並修改(如果覺得我製作的好,也煩請加入我的logo) 5.可結合後端伺服器 00.art 相本集資料夾 com 奶綠茶的Class檔 swfaddress SWFAddress資料夾 swfobject swfobject資料夾 XML galleryV3.fla 原始檔 index.html 主檔html SWFAddress.as SWFaddressEvent.as Source Code Download 解壓密碼:回覆文章,即可看見Password

超好用的無限免費網頁空間,無廣告,無流量限制

大家好,我是奶綠茶 今天來教大家如何申請一個無限免費速度又快的網頁空間 1 首先到  https://github.com/ 申請帳號(一直下一步,下一步,下一步) 2 到你的個人頁,切換上方的 tab 到 Repositories, 按下右鍵的 new 3 Repository name 一定要是這樣的格式 username.github.io 我的 github 網址是 github.com/milkmidi 那就要輸入 milkmidi.github.io 選擇 public, 這樣別人才看的到 private 有其他用途, 而且要付費才能使用 完成後按下 Create repository 5 安裝 SourceTree github 並不支援 FTP 或是網頁上傳,一定要透過指令碼 在這我們選用有圖型介面的軟體,方便大家學習 https://www.sourcetreeapp.com/ 下載並安裝 啟動後登入你的 github 帳號 6 clone 你的 github io 專案 右上角有個 Clone or download 點選後 複製 https 連結(不要選到 ssh ) 7 將 https 的連結貼到 SourceTree 8 上傳 html 到本機 github.io 資料夾,放一個 index.html 切換到 SourceTree, 這時會看到 Unstaged files 的欄位 選擇 Stage All 9 git 要求每次的 Commit, 都一定要打說明文字(好習慣) 輸入完成後,按下右邊的 Commit 10 發佈(Push),這樣就完成啦 可以到你的 http://milkmidi.github.io/ 去查看檔案有沒有出來 其他 Commit 可以想像是做一個記錄,你可以很多的 Commit 最後再一次 Push 上去 github 原本是給程式設計師用的版本控管服務 免費版提供無限空間讓你放檔案,但一定要是 public 想要有私有的 Project ,就只能付費 github.io 只能放靜態檔案,php, aspx 服務並不支援。 祝大家學習愉快 轉載請註明出處 奶綠的 github.io S