Beautifl - Flash Gallery

Thumbnail : Unknown Attractor
Unknown Attractor
alumican_net 2009-08-27 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/**
 * こりずにまたカオスです
 * 
 * 名前は知らないけど、個人的にはこのアトラクタが一番好きだったりします
 * かっこいいよね!
 * 
 * パラメータによっては描画に時間がかかるので
 * もう一度画面をクリックしてください
 * 
 * @author alumican.net
 */
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.Sprite;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import com.flashdynamix.utils.SWFProfiler;
    
    public class UnknownAttractor extends Sprite
    {
        private const ZEROS:Point = new Point(0, 0);
        
        //パーティクル数
        private const N:uint = 10000;
        
        //linked listの先頭インスタンス
        private var _head:Particle;
        
        //描画用
        private var _canvas:BitmapData;
        private var _buffer:BitmapData;
        private var _w:uint = 465;
        private var _h:uint = 465;
        
        private var _blur:BlurFilter      = new BlurFilter(8, 8, 3);
        private var _trans:ColorTransform = new ColorTransform(1, 1, 1, 0.9);
        
        //パラメータ群
        private var _a:Number;
        private var _b:Number;
        private var _c:Number;
        private var _d:Number;
        
        private var _theta:Number;
        private var _sin:Number;
        private var _cos:Number;
        private var _scale:Number;
        private var _color:uint;
        
        private var _count:uint = 0;
        
        
        //--------------------------------------------------
        //コンストラクタ
        public function UnknownAttractor():void
        {
            Wonderfl.disable_capture();
            
            stage.frameRate = 60;
            
            //パーティクル生成
            var o:Particle = _head = new Particle();
            for (var i:uint = 0; i < N; ++i)
            {
                o = o.next = new Particle();
            }
            
            //イベントリスナ登録
            addEventListener(Event.ENTER_FRAME, _update);
            stage.addEventListener(MouseEvent.CLICK, _reset);
            
            //描画用BitmapData生成
            _canvas = new BitmapData(_w, _h, true, 0xffffff);
            _buffer = _canvas.clone();
            addChild(new Bitmap(_canvas));
            
            //パラメータ群の初期化
            _reset();
            
            _a     = -1.47;
            _b     = 0.9;
            _c     = -4;
            _d     = 30.0;
            _theta = 0;
            _sin   = Math.sin(_theta);
            _cos   = Math.cos(_theta);
            _scale = 10;
            
            //プロファイラの表示
            SWFProfiler.init(this);
        }
        
        //--------------------------------------------------
        //パラメータ群の再設定
        private function _reset(e:MouseEvent = null):void
        {
            _buffer.fillRect(_buffer.rect, 0xffffff);
            
            //パラメータの再設定と調整
            _a     = Math.random() * (1.6  + 1.3) - 1.3;
            _b     = Math.random() * (0.99 - 0.8) + 0.8;
            _c     = -4.0;
            _d     = 30.0;
            
            _theta = Math.random() * 2 * Math.PI;
            _sin   = Math.sin(_theta);
            _cos   = Math.cos(_theta);
            _scale = (Math.random() * 6 + 6) * _w / 465;
            
            _color = int(Math.random() * 0x66) << 16 | int(Math.random() * 0x66) << 8 | int(Math.random() * 0x66);
            
            _spreadParticle();
        }
        
        //--------------------------------------------------
        //パーティクルを分散させる
        private function _spreadParticle():void
        {
            var p:Particle = _head;
            do {
                p.x = (Math.random() - 0.5) * _w;
                p.y = (Math.random() - 0.5) * _h;
            }
            while (p = p.next);
        }
        
        //--------------------------------------------------
        //毎フレーム更新
        private function _update(e:Event):void
        {
            if (++_count % 120 == 0)
            {
                _count = 0;
                _spreadParticle();
            }
            
            //パーティクルの座標を更新する
            _buffer.lock();
            var p:Particle = _head;
            var x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number;
            do {
                //座標の更新
                x0 = p.x;
                y0 = p.y;
                x1 = p.x = _a * x0 + _b * y0 + _c + _d / (1 + x0 * x0);
                y1 = p.y = -x0;
                
                //回転とスケール
                x2 = _w / 2 + _scale * (_cos * x1 - _sin * y1);
                y2 = _h / 2 + _scale * (_sin * x1 + _cos * y1);
                
                //描画
                _buffer.setPixel32(x2, y2, (Math.min(0xff, (_buffer.getPixel32(x2, y2) >>> 24) + 0x03) << 24) | _color);
            }
            while (p = p.next);
            _buffer.unlock();
            
            //キャンバスに描画する
            _canvas.lock();
            _canvas.colorTransform(_canvas.rect, _trans);
            _canvas.applyFilter(_canvas, _canvas.rect, ZEROS, _blur);
            _canvas.draw(_buffer);
            _canvas.unlock();
        }
    }
}

//--------------------------------------------------
//パーティクルクラス
internal class Particle
{
    public var x:Number;
    public var y:Number;
    public var next:Particle;
}