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

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

今回からは2回に渡って、アニメーションするFlashを作っていきます。今回は、自力でアニメーション処理を書く方法を紹介します。

Timerクラスでアニメーション

Flashにはアニメーションに便利なTimerクラスが用意されています。Timerクラスを利用すると、一定時間ごとに特定の処理を行うことができるようになります。

前回のサンプルをベースに、円がじわじわとフェードアウトするものを作ってみました。前回からの変更点を太字にしています。

package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.utils.Timer;
    
    public class Anime1 extends Sprite {
        public function Anime1():void {
            // クリックイベントを監視する
            stage.addEventListener("click", clickHandler);
        }

        private function clickHandler(event:MouseEvent):void {
            // 円を作成
            var s:Sprite = new Sprite();
            s.graphics.beginFill(Math.random() * 0x1000000);
            s.graphics.drawCircle(0, 0, 10);
            s.graphics.endFill();
            addChild(s);

            // 円をクリックされた位置に移動
            s.x = event.stageX;
            s.y = event.stageY;

            // タイマー開始
            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;
            });
            timer.addEventListener("timerComplete", function(event:Event):void {
                removeChild(s);
            });
        }
    }
}

Anime1.asとして保存して、コンパイルします。

mxmlc Anime1.as

Flashの完成です。クリックすると円が表示され、徐々に消えていきます。

それでは、Timerクラスの使い方を見ていきましょう。

タイマーの作成

まずは、Timerオブジェクトの生成です。

var timer:Timer = new Timer(50, 20);

Timerオブジェクトを作成して、timerという変数で参照しています。コンストラクタには2つのパラメータを指定します。

Timer(タイマー実行の間隔:Number, 回数:int = 0)

今回は50ミリ秒間隔で20回呼び出されるタイマーを作成しています。50ミリ秒×20回=1秒ですので、アニメーションは約1秒間再生さることになります。

次に、start()メソッドを呼び出して、タイマーを開始しています。

timer.start();

フェードアウトの処理

タイマーを開始すると、コンストラクタで指定した間隔で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);
});

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

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

どんどん大きくなる円

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

    // 初期スケールの設定
    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」を使ったアニメーションをご紹介します。

おすすめ記事

記事・ニュース一覧