プログラマのためのFlash遊び方

第5回 動きのある Flash を作る(前編)

この記事を読むのに必要な時間:およそ 3 分

フェードアウトの処理

タイマーを開始すると,コンストラクタで指定した間隔でtimerイベントが発生します。timerイベントを監視するには,TimerオブジェクトのaddEventListener()メソッドを利用します。

イベントリスナでは,Timerオブジェクトの2つのプロパティを参照しています。

timer.addEventListener("timer", function(event:Event):void {
  var ratio:Number = timer.currentCount / timer.repeatCount;
  s.alpha = 1 - ratio;
});

currentCountプロパティは現在の呼び出し回数を表します。repeatCountプロパティは呼び出される合計回数(ここでは必ず20)です。

タイマーをスタートすると,50ミリ秒後に,1回目のイベントが発生します。このとき,currentCountは1なので,ratioは1/20=0.05となります。2回目(100ミリ秒後)は2/20=0.10です。このように,ratioの値はどんどん増えていき,最後の20回目の呼び出し(1,000ミリ秒後)には,20/20=1となります。

alphaプロパティは透明度を表す0~1までの数値です(0が完全に透明,1が不透明⁠⁠。今回の例では,1から0に向かって値が変化して行くので,どんどん透明になっていくわけですね。

アニメーション終了時の処理

20回のタイマー呼び出しが終了すると,TimerオブジェクトはtimerCompleteイベントを送出します。

今回の例ではtimerCompleteイベントのハンドラでアニメーションの終了処理を行っています。

timer.addEventListener("timerComplete", function(event:Event):void {
  removeChild(s);
});

ここでは,不要になった円をステージ上から削除しています。この処理をしないと,透明な円がステージ上に溜まっていってしまいます。

ActionScriptはシングルスレッド

以上でソースコードの解説は終了ですが,1点補足しておきましょう。今回のソースコードではstart()メソッド呼び出しのあとにイベント登録していますね。他の言語でスレッドを使ったプログラミングに親しんでいる方は「イベント登録する前に,1回目のイベントが発生したらどうするんだ」と感じるかもしれません。安心してください。そんな心配はありません。

というのも,ActionScriptは全ての関数がシングルスレッドで実行されています。clickHandler()メソッドを実行中に,別のスレッドからイベントハンドラが呼ばれることはありません。clickHandler()メソッド終了後に,タイマーイベントが発生し,イベントハンドラが呼ばれます。つまり,start()してからイベント登録しても問題ないのです。

少し改造して動きをつける

どんどん大きくなる円

フェードアウトだけではつまらないので,もう少し動きをつけてみます。

    // 初期スケールの設定
    s.scaleX = s.scaleY = 0;
    
    // タイマー開始
    var timer:Timer = new Timer(50, 20);
    timer.start();
    timer.addEventListener("timer", function(event:Event):void {
        var ratio:Number = timer.currentCount / timer.repeatCount;
        s.alpha = 1 - ratio;
        s.scaleX = 5 * ratio;
        s.scaleY = 5 * ratio;
    });

scaleXプロパティ,scaleYプロパティは拡大率を表します。1.0が100%です。拡大率を0~5.0までアニメーションさせてみました。

試しにクリックしてみてください。円がどんどん大きくなっていきますね。

回転しながら迫ってくる円

今度は,円を中心からずらして描画してみます。

    s.graphics.drawCircle(20, 0, 10);  // 中心座標をずらす
    ...

    // 初期スケールの設定
    s.scaleX = s.scaleY = 0;

    // タイマー開始
    var timer:Timer = new Timer(50, 20);
    timer.start();
    timer.addEventListener("timer", function(event:Event):void {
        var ratio:Number = timer.currentCount / timer.repeatCount;
        s.alpha = 1 - ratio;
        s.scaleX = 5 * ratio;
        s.scaleY = 5 * ratio;
        s.rotation = 360 * ratio;
    });

rotationプロパティを変化させることで,回転しながら迫ってくるような効果が得られます。マウスを連打してもきれいですね。

まとめ

今回は自力でアニメーションを行う方法を紹介しました。また,少しの修正で見た目の印象が大きく変わるところご覧いただきました。

このまま拡張していってもいいのですが,実は今の実装には少し無駄があります。今は円を表示するたびにタイマーを作成しています。複数の円が同時に表示されているときには,背後で複数のタイマーが動きます。単純なアニメーションなら大きな問題にはなりませんが,複雑なものを作成するにはパフォーマンスが気になります。

それを解決してくれるのが,アニメーションライブラリです。パフォーマンスが最適化されているだけでなく,その他にも便利な機能が盛りだくさんです。また,アニメーションに必要な処理がライブラリに隠蔽されるので,ソースコードがシンプルになるというメリットもあります。

次回は,有名なアニメーションライブラリ「tweener」を使ったアニメーションをご紹介します。

著者プロフィール

最田健一(さいたけんいち)

有限会社 CO-CONV勤務のプログラマ。京都在住の京都好き。趣味で ActionScript 3.0やFlex 2を触っていたら,いつの間にか仕事でも使うことになっていた。個人ブログは「てっく煮ブログ」。

URLhttp://tech.nitoyon.com/