forked from: パーティクルの勉強2

by Shiro0330 forked from パーティクルの勉強2 (diff: 3)
♥0 | Line 101 | Modified 2011-06-14 18:13:23 | MIT License
play

ActionScript3 source code

/**
 * Copyright Shiro0330 ( http://wonderfl.net/user/Shiro0330 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8jkh
 */

// forked from umi_kappa's パーティクルの勉強2
// forked from Saqoosha's Snow
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.MovieClip;
    import flash.display.PixelSnapping;
    import flash.events.Event;
    import flash.filters.BlurFilter;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    
    public class Main extends MovieClip
    {
        //重力
        private static const GRAVITY:Number = 10;
        
        //一番遅いときのスピード
        private static const DRAG:Number = 0.3;
        
        //パーティクルを描画する
        private var _canvas:BitmapData;
        
        //きらきらを描画する
        private var _glow:BitmapData;
        
        //きらきらをdrawするときに使う
        private var _glowMtx:Matrix;
        
        //フォーカスマップ パーティクルの速度関係
        private var _forceMap:BitmapData;
        
        //パーティクルが入る配列
        private var _snow:Array;
        
        //--------------------------------------------------------------------------
        //
        //  コンストラクタ
        //
        //--------------------------------------------------------------------------
        public function Main() 
        {
                        //フレームレートの設定
                        stage.frameRate = 60;
                        
            // カンバスをつくる。ここに 1 pixel ずつ描いていくよ
            _canvas = new BitmapData(465, 465, false, 0x0);
            addChild(new Bitmap(_canvas));
            
            // キラキラを描く用のん。カンバスの 4 分の 1 のサイズ
            _glow = new BitmapData(465 / 4, 465 / 4, false, 0x0);
            var _bm:Bitmap = new Bitmap(_glow, PixelSnapping.NEVER, true);
            addChild(_bm);
            // 4 倍にする。
            _bm.scaleX = _bm.scaleY = 4;
            // 加算モードで合成
            _bm.blendMode = BlendMode.ADD;
            _glowMtx = new Matrix(0.25, 0, 0, 0.25);
            
            
            // 雪を積もらせるかたちを BitmapData に描く。
            var _tf:TextField = new TextField();
            _tf.defaultTextFormat = new TextFormat("Verdana", 64, 0xffffff, true);
            _tf.autoSize = TextFieldAutoSize.LEFT;
            _tf.text = "Shiro";
            _tf.x = (465 - _tf.width) / 2;
            _tf.y = (465 - _tf.height) / 2;
            
            //フォーカスマップ パーティクルの速度関係
            _forceMap = new BitmapData(465, 465, false, 0x0);
            _forceMap.draw(_tf, _tf.transform.matrix);
            _forceMap.applyFilter(_forceMap, _forceMap.rect, new Point(0, 0), new BlurFilter(8, 8));
            
            // 雪パーティクルはここにいれておくよ。
            _snow = [];
            
            addEventListener(Event.ENTER_FRAME, update);
        }
        
        
        //----------------------------------
        //  ENTER_FRAME
        //----------------------------------
        private function update(e:Event):void 
        {
            // いっぱい setPixel するときは必ず lock しよう
            _canvas.lock();
            // カンバスをクリア
            _canvas.fillRect(_canvas.rect, 0x0);
            
            //パーティクルの数
            var n:int = _snow.length;
            //落ちるスピード
            var d:Number;
            // あらかじめ重力を計算しとく
            var gravity:Number = GRAVITY / 1000;
            
            while (n--)
            {
                var p:SnowParticle = _snow[n];
                // まず重力を加える
                p.vy += gravity * p.s;
                // 空気抵抗
                p.vy *= 0.99;
                // forceMap にもとづいて抵抗値を計算。黒→速い、白→遅い。
                d = 1 - (_forceMap.getPixel(p.x, p.y) / 0xffffff) * DRAG;
                // forceMap から得た抵抗値を適用
                p.vy *= d;
                // 動かす
                p.y += p.vy;
                // 雪 1 粒描く
                _canvas.setPixel(p.x, p.y, p.c);
                
                // もし画面外にでちゃったら
                if (p.y > stage.stageHeight) {
                    // とりのぞく
                    _snow.splice(n, 1);
                }
            }
            
            // lock したやつは必ず unlock
            _canvas.unlock();
            
            // キラキラを描く _glowMtxできらきらの移動量を1/4にしている
            _glow.draw(_canvas, _glowMtx);
            
            // 新規で雪を発生させますよ
            n = 10;
            while (n--) {
                emitParticle(Math.random() * stage.stageWidth, 0, Math.random() + 0.5);
            }
        }
        
        //----------------------------------
        //  雪を 1 粒発生させる関数
        //----------------------------------
        public function emitParticle(ex:Number, ey:Number, s:Number = 1, c:int = 0xffffff, vx:Number = 0, vy:Number = 0):void {
            // 作って
            var p:SnowParticle = new SnowParticle();
            
            // パラメータ設定して
            p.x = ex;
            p.y = ey;
            p.vx = vx;
            p.vy = vy;
            p.s = s;
            p.c = c;
            
            // 保存
            _snow.push(p); 
        }
    }
}

//----------------------------------
//  パーティクル
//----------------------------------
class SnowParticle {
    
    //現在のパーティクルの座標
    public var x:Number;
    public var y:Number;
    
    //毎フレームのパーティクルの移動量
    public var vx:Number;
    public var vy:Number;
    
    //毎フレームのパーティクルが落ちる長さ率
    public var s:Number;
    
    //色
    public var c:int;
    
    public function SnowParticle() {
        this.x = 0;
        this.y = 0;
        this.vx = 0;
        this.vy = 0;
        this.s = 1;
        this.c = 0xffffff;
    }
}

Forked