In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: 炎のエフェクト

source : http://actionsnippet.com/?p=1750
炎エフェクトを描画したBitmapDataをSpriteの子として持たせるようにしました。
炎のスケーリング方法を少し変えて、横幅が縦幅よりも早く縮小するようにしました。
copyPixelsを勉強するためにFORKさせて頂きました。
レイヤーを重ねるようなイメージではなく、まるごとピクセルをコピーするというイメージなのですね。
Get Adobe Flash player
by Hado_A 23 Sep 2009
/**
 * Copyright Hado_A ( http://wonderfl.net/user/Hado_A )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1qW9
 */

// forked from kato's 炎のエフェクト
// source : http://actionsnippet.com/?p=1750
// 炎エフェクトを描画したBitmapDataをSpriteの子として持たせるようにしました。
// 炎のスケーリング方法を少し変えて、横幅が縦幅よりも早く縮小するようにしました。
// copyPixelsを勉強するためにFORKさせて頂きました。
// レイヤーを重ねるようなイメージではなく、まるごとピクセルをコピーするというイメージなのですね。

package
{
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.GradientType;
    import flash.display.SpreadMethod;
    import flash.filters.BlurFilter;
    import flash.filters.BitmapFilterQuality;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;
    import flash.events.Event;
    import net.hires.debug.Stats;

    [SWF(width="465", height="465", backgroundColor="0x555555", frameRate="30")]

    public class ParticleFlame extends Sprite 
    {
        //------------------------------------------------------
        // const
        //------------------------------------------------------
        
        // グラデーション
        private const COLORS            :Array           = [0xFFCC33, 0xFF0000];
        private const ALPHAS            :Array           = [0.6, 0.2];
        private const RATIOS            :Array           = [50, 200];
        private const TWO_PI            :Number          = Math.PI * 2;
        private const CANVAS_SIZE       :Number          = 465;

        //------------------------------------------------------
        // var
        //------------------------------------------------------

        private var canvas        :BitmapData;
        private var overlay       :BitmapData;
        private var particles     :Dictionary;
        private var blurs         :Array;
        private var m_stage       :Sprite;
        
        //------------------------------------------------------
        // method
        //------------------------------------------------------
        
        //------------------------------------------------------
        /**
         * コンストラクタ
         */
        public function ParticleFlame()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.LOW;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            init();
        }
        
        //------------------------------------------------------
        /**
         * 初期化。
         */
        private function init():void
        {
            canvas = new BitmapData(CANVAS_SIZE, CANVAS_SIZE, true, 0x00000000); // 実際に描画されるもの
            overlay = new BitmapData(CANVAS_SIZE, CANVAS_SIZE, true, 0x00000000); // canvasにコピーして上書きするためのもの
            m_stage = new Sprite(); // このスプライトをいじれば、容易に炎を表示・非表示切り換えられる
            //m_stage.visible = false;
            particles = new Dictionary(true); // パーティクルクラスを格納する
            
            // ブラー(ぼかし)フィルタ
            blurs = new Array();
            blurs.push(new BlurFilter(6, 6, BitmapFilterQuality.HIGH));

            addChild(m_stage);
            m_stage.addChild(new Bitmap(canvas));
            addChild(new Stats());

            addEventListener(Event.ENTER_FRAME, loopHandler);
        }
        
        //------------------------------------------------------
        /**
         * 毎フレームイベント。
         */
        private function loopHandler(event:Event):void
        {
            // パーティクルの作成
            for(var i:int = 0; i < 3; i++) { createParticle(); }
            
            // canvasをクリア(canvasにoverlayを丸々コピペ)
            canvas.copyPixels(overlay, canvas.rect, new Point(), overlay, new Point(), false);
        }

        //------------------------------------------------------
        /**
         * パーティクルを作成。
         */
        private function createParticle():void
        {
            var p:Particle = new Particle();
            
            // パーティクルのサイズ
            var diameter:Number = Math.random() * 60 + 5; // 直径(+nで最小の直径を決めている)
            var radius:Number = diameter / 2;

            // グラデーションの性質を決めるマトリクスを作成
            var mat:Matrix = new Matrix();
            mat.createGradientBox(diameter, diameter, 0, -radius, -radius);

            // グラデーション円描画開始
            p.graphics.beginGradientFill(GradientType.RADIAL, COLORS, ALPHAS, RATIOS, mat);
            p.graphics.drawCircle(0, 0, radius);
            p.graphics.endFill();
            
            // 表示位置
            p.posX = stage.mouseX;
            p.posY = stage.mouseY;
            
            // X座標の遷移を決定づけるパラメータ
            p.theta = Math.random() * TWO_PI;
            p.inc = Math.random() * 0.4 + 0.01;
            p.rad = Math.random() * 2 + 1;
            
            // Y座標の遷移
            p.velY = -Math.random() * 5 + 0.5;
            
            // ブラーフィルター設定
            p.filters = blurs;
            
            // Dictionaryにこのパーティクルを加える
            particles[p] = p;
            
            // ひとつひとつのパーティクルに対して毎フレーム処理イベント
            p.addEventListener(Event.ENTER_FRAME, runParticleHandler);
        }

        //------------------------------------------------------
        /**
         * ひとつのパーティクルを動かす。
         */
        private function runParticleHandler(event:Event):void
        {
            var p:Particle = event.currentTarget as Particle;
            
            // 移動
            p.posX += p.velX;
            p.posY += p.velY;
            p.x = p.posX;
            p.y = p.posY;
            
            // 次フレームの移動方向
            p.velX = p.rad * Math.cos(p.theta);
            p.theta += p.inc;
            
            if (p.scaleX > 0.06) { p.scaleX -= 0.06; }

            // 縮小されて見えなくなったら削除する
            if (p.scaleY < 0)
            {
                particles[p] = null;
                p.removeEventListener(Event.ENTER_FRAME, runParticleHandler);
            }
            else
            {
              p.scaleY -= 0.03;
            }

            // 描画
            // pのtransform.matrixには p.x, p.scaleX などに関係する行列が入っている?
            canvas.draw(p, p.transform.matrix, p.transform.colorTransform, BlendMode.ADD);
        }
        
    }

}

//--------------------------------------
//
//  Class Particle
//
//--------------------------------------
import flash.display.Sprite;

internal class Particle extends Sprite
{
    public var velX:Number;
    public var velY:Number;
    public var posX:Number;
    public var posY:Number;
    public var theta:Number;
    public var inc:Number;
    public var rad:Number;

    public function Particle()
    {
        this.velX = 0;
        this.velY = 0;
        this.posX = 0;
        this.posY = 0;
        this.theta = 0;
        this.inc = 0;
        this.rad = 0;
    }
}