Reinit_creative log Reinit_creative log rss

Reinit_creative log

about ActionScript3 and Design memo.

条件分岐DoTweener

2009.04.15

--------------------------
この記事は、訂正版がありますので、[訂正]条件分岐DoTweener を参照してください。
--------------------------

別にDoTweenerに限ったわけではありません。 動的にコマンドの処理を変更したいと思うことってよくあります。 その一例としてメモ。

Spriteクラスのインスタンスspのalphaが0だったら、1st_DoTweenerを行ってalphaを1にしてから、2番目のDoTweenerでspのalphaを0にする場合は。
var sp:Sprite = new Sprite;
sp.alpha=1;
new SerialList(null,
	function():void
	{
		if (sp.alpha==1) {
			new SerialList(null,
				new Func(trace,["1st_DoTweener開始"]),
				//1st_DoTweener
				new DoTweener(sp, { alpha:0, time:2 } ),
				new Func(trace,["1st_DoTweener終了"])
			).execute();
		}
	},
	new Func(trace,["2nd_DoTweener開始"]),
	//2nd_DoTweener
	new DoTweener(sp, { alpha:0, time:3 } ),
	new Func(trace,["2nd_DoTweener終了"])
).execute();
とスクリプトを書いてみます。 期待している出力結果は、下のような感じです。
1st_DoTweener開始
1st_DoTweener終了
2nd_DoTweener開始
2nd_DoTweener終了
が、結果は、
1st_DoTweener開始
2nd_DoTweener開始
2nd_DoTweener終了
となります。 1st_DoTweenerコマンドがセットされているSerialListは、Funcコマンド(コマンド内での匿名関数は、自動的にFuncコマンドに変換される)の中に入れ子状態で入っています。よって、FuncコマンドとSerialListは、同時に処理されます。 SerialList内は1st_DoTweenerの待機処理に入りますが、SerialListの親にあたるFuncコマンドは、次の処理に進み、2nd_DoTweenerが実行されます。
見た目の結果からいくと、1st_DoTweenerと2nd_DoTweenerのターゲットインスタンスはspです。 spのalpha値は0になる前に1になります。よって、何も変化しません。 加えて、1st_DoTweenerはタイムアウトエラーを起こします。 下記のようなエラー文。

[ERROR]      コマンドで CommandTimeOutError エラーが発生。
これは、同じインスタンスに対して、DoTweenerの実行がかぶった場合に、DoTweener内部でexecuteCompleteメソッドが呼ばれないから起こります(たぶん)。 うまく走らせるためには、Funcコマンドで、DoTweenerの処理を待たせればいいのだと思います。
package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import jp.progression.commands.DoTweener;
	import jp.progression.commands.Func;
	import jp.progression.commands.SerialList;
	
	/**
	 * ...
	 * @author ReInit_creative | Shunsuke Ohba
	 */
	public class FuncTest2 extends Sprite
	{
		
		public function FuncTest2() 
		{
			var sp:Sprite = new Sprite;
			sp.alpha = 1;
			var scope:FuncTest2 = this;
			
			new SerialList(null,
				function():void
				{
					//Funcコマンドを待機状態にする
					this.eventType = "funcComplete";
					this.dispatcher = scope;
					if (sp.alpha==1) {
						new SerialList(null,
							new Func(trace,["1st_DoTweener開始"]),
							//1st_DoTweener
							new DoTweener(sp, { alpha:0, time:2 } ),
							new Func(trace, ["1st_DoTweener終了"]),
							//DoTweenerが終了したので1st_DoTweenerが終了したイベントを発行する
							function():void
							{
								dispatchEvent(new Event("funcComplete"));
							}
						).execute();
					}
				},
				new Func(trace,["2nd_DoTweener開始"]),
				//2nd_DoTweener
				new DoTweener(sp, { alpha:0, time:3 } ),
				new Func(trace,["2nd_DoTweener終了"])
			).execute();
		}
	}
}
Funcコマンドにイベント待ちの処理を行えば、1st_DoTweenerが終了した時点でFuncコマンドを次の処理へ進めることが出来ます。 出力結果は、
1st_DoTweener開始
1st_DoTweener終了
2nd_DoTweener開始
2nd_DoTweener終了
と期待通りの出力です。
以下の部分をもっとシンプルに書けないかなと思って、
new SerialList(null,
	new Func(trace,["1st_DoTweener開始"]),
	//1st_DoTweener
	new DoTweener(sp, { alpha:0, time:2 } ),
	new Func(trace, ["1st_DoTweener終了"]),
	//DoTweenerが終了したので1st_DoTweenerが終了したイベントを発行する
	function():void
	{
		dispatchEvent(new Event("funcComplete"));
	}
).execute();
以下のように書き直してみました。(traceは省いています。)
new SerialList(null,
	//1st_DoTweener
	new DoTweener(sp, { alpha:0, time:3 } ).after(dispatchEvent,[new Event("funcComplete")])
).execute();
afterメソッドを使ってdispatchEventでイベントを発行できないかなーって思ったのですが、駄目でした。 エラー文。
TypeError: Error #1034: 強制型変換に失敗しました。[]@26d1699 を flash.events.Event に変換できません。
ソースを読んで調べてみようと思います。
前々回記事のFuncコマンドをParallelListで処理すると に引き続いてFuncコマンド万歳なポストでしたっと。

update 2010.03.01...

[関連記事]

My Icon

Flash+デザインを仕事としています。
info[at]reinit.info
>>detail

レコメンド

ActionScript3アニメーション

ActionScriptアニメーション

アニメーションに関する基礎が得られる本。
コレを読んで、ASが楽しくなった。