条件分岐DoTweener

2009.04.15  Category:ActionScript3.0

————————–
この記事は、訂正版がありますので、[訂正]条件分岐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]     <Func : command_2> コマンドで 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コマンド万歳なポストでしたっと。

RSS Reader
RSSリーダーへの登録をお願いします。
トップへ戻るボタン

著者

大庭俊介
株式会社サイバーエージェント所属の紙デザイナー上がりのFlashデベロッパー。アメーバピグ内のコンテンツ企画、実装を手掛けています。金沢美術工芸大学出身。
follow twitter

おすすめ

イニシエーション・ラブ/ 乾 くるみ

最後の2行目を見たときにマジでビビり、最初からまた読み返してしまい、ネタばれのサイトに行き着く。

フィジカルコンピューティングを「仕事」にする

初めての共著作。Kinect作品PiggFighterの項目を執筆しています。

基礎からのiOS SDK

iPhone開発ド素人の僕が現在、勉強中の本。結構丁寧に書かれてあって分かりやすい。特にWebブラウザ作成のチュートリアル部分の説明でかなり理解が深まった。