ActionScriptでビットマップエフェクト

昨日に引き続き、学習中。

ブラウザで無料ではじめるActionScript 3.0 ―It's a wonderfl world―

ブラウザで無料ではじめるActionScript 3.0 ―It's a wonderfl world―

今日は1-4 時計を作ろうを読んだ。
TimerEventはまだ触ったことがないからちょっとやってみたいと思ったんだけど、面白そうだと思ったのはビットマップエフェクト。
Electrogram clock - wonderfl build flash online
このサンプルについての解説が載っていて、現れては消えていく線はビットマップエフェクトを使って表現されているそうな。

var _bmp:Bitmap = new Bitmap();
var _bmd:BitmapData = new BitmapData(465, 465, false, 0x000000);
_bmp.bitmapData = _bmd;

のようにしてBitMapDataインスタンスを登録したBitMapインスタンスを用意してaddChild()などで画面に追加、あとはBitmapDataインスタンスに対しdraw()メソッドで引数に渡したDisplayObjectのスナップショットをそこに描画したり、フィルタリングしたりできるらしい。


昨日書いたマウスの動きを追従する円の残像のようなものを、線に対し連続でBlurFilterをかけることで表現できるのでは?と書いてみた。

// forked from sugyan's forked from: flash on 2010-1-21
// forked from sugyan's flash on 2010-1-21
/* ドラッグ操作で滲むような線を描く */
package {
    import flash.filters.BlurFilter;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.events.Event;
    import flash.events.MouseEvent;

    public class FlashTest extends Sprite {
        private var _line:MyLine = new MyLine(5, 0xFF0000);
        private var _bmp:Bitmap = new Bitmap();
        private var _bmd:BitmapData = new BitmapData(465, 465, false, 0x000000);
    	    
        public function FlashTest() {
            _bmp.bitmapData = _bmd;
            addChild(_bmp);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, function (event:MouseEvent):void {
                _line.startDraw(new Point(event.stageX, event.stageY));
                stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            });
            stage.addEventListener(MouseEvent.MOUSE_UP, function (event:MouseEvent):void {
                stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            });
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onMouseMove(event:MouseEvent):void {
            _line.drawLine(new Point(event.stageX, event.stageY));
            _bmd.draw(_line);
        }
        
        private function onEnterFrame(event:Event):void {
            _bmd.applyFilter(_bmd, _bmd.rect, new Point(0, 0), new BlurFilter(5, 5));
        }
    }
}


import flash.geom.Point;
import flash.display.Sprite;

class MyLine extends Sprite {
    private var _prevX:Number;
    private var _prevY:Number;
    private var _thickness:Number;
    private var _color:uint;

    public function MyLine(thickness:Number, color:uint) {
        _thickness = thickness;
        _color = color;
    }
	
    public function startDraw(point:Point):void {
        _prevX = point.x;
        _prevY = point.y;
    }
	
    public function drawLine(point:Point):void {
        graphics.clear();
        graphics.lineStyle(_thickness, _color);
        graphics.moveTo(_prevX, _prevY);
        graphics.lineTo(point.x, point.y);
        _prevX = point.x;
        _prevY = point.y;
    }
}

出来たのがコレ -> forked from: forked from: flash on 2010-1-21 - wonderfl build flash online
forkして作ったけど結局全然別物になってしまったw
ボタンダウンしている時だけマウス移動に伴い連続で直線がBitmapDataに描画されていくのだけど、同時にENTER_FRAMEのイベントで常時BlurFilterでぼかしをかけているので時間が経つと消えていく。


なるほどー、こうやってエフェクトかけることができるんだ!
BitmapFilterは他にも種類があるしBitmapDataにも色々なメソッドがある。組み合わせて使いこなすことでもっとたくさんのエフェクトができるようになるんだろうなー。
せっかくなので時計っぽいものも作っておきたい。次は2章だ!!

追記

どうもマウスを速く動かすと線がカクカクしてしまう。
隣の席にいる某天才に訊いてみたところ、MOUSE_MOVEでのイベントで描画するよりもENTER_FRAMEの方が優先度が高いはずなのでより滑らかに書けるのでは?と言われ、書き換えてみた。
forked from: forked from: forked from: flash on 2010-1-21 - wonderfl build flash online
結局あまり変わらなかった…残念。