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

Metaball with PerlinNoise

Get Adobe Flash player
by linktale 28 May 2012
/**
 * Copyright linktale ( http://wonderfl.net/user/linktale )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1FJF
 */

/*
元はこちら
http://wonderfl.net/c/lsVb
マウスダウンした状態でマウスを動かすと移動します。
http://linktale.net/
*/
package {
    //import com.flashdynamix.utils.SWFProfiler;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.BlurFilter;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    [SWF(backgroundColor="0xffffff", frameRate="40")] 

    public class Trick extends Sprite { 
        //Image
        private var perlinOfset:Array = [new Point(0, 0), new Point(0, 0)];
        private var _blue:BlurFilter;
        
        //メタボールの数
        private var _numBlobs:uint = 4;
        
        //メタボールの初期ポジション
        private var _blogPx:Array = new Array(20 ,20 , 90, 90);
        private var _blogPy:Array = new Array(60, 80, 100, 120);
        
        //メタボールの速度
        private var _blogDx:Array = new Array(1, 1, -1, -1);
        private var _blogDy:Array = new Array(-1, -1, -1, -1);
        
        //ビットマップ
        private var _bmpData1:BitmapData;
        private var _bmpData2:BitmapData;
        
        //各ピクセルの色の関係値
        private var _vx:Array = new Array();
        private var _vy:Array = new Array();
        
        //Drag
        private var _downFlg:Boolean = false;
        
        public function Trick():void {
            //SWFProfiler.init(stage, this);
            //Wonderfl.capture_delay(8);
            Wonderfl.disable_capture();
            
            init();
        }
    
        
        private function init():void {
            //処理速度を抑えるため
            scaleX = scaleY = 3;
            //ブラー
            _blue = new BlurFilter(10, 10);
            //ビットマップ配置        
            _bmpData1 = new BitmapData(155, 155);
            var bitmap1:Bitmap = new Bitmap(_bmpData1);
            addChild(bitmap1);
            
            _bmpData2 = _bmpData1.clone();
            var bitmap2:Bitmap = new Bitmap(_bmpData2);
            addChild(bitmap2);
            bitmap2.blendMode = BlendMode.OVERLAY;
            
            //描画
            addEventListener(Event.ENTER_FRAME, draw);
            
            //マウス
            stage.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
                _downFlg = true;
            });
            stage.addEventListener(MouseEvent.MOUSE_UP, function():void {
                _downFlg = false;
            });
        }
        
        private function draw(e:Event = null):void {
            var x:uint, y:uint, i:uint;
            var color:uint, r:uint, g:uint, b:uint;
            
            //perlinNoise
            _bmpData1.perlinNoise(24, 24, 2, 1000, true, true, 7, false, perlinOfset);
            perlinOfset[0].x += 1;  
            perlinOfset[0].y += 1;  
             
            for (i = 0; i < _numBlobs; ++i) {
                //速度追加
                if(_downFlg){            
                    _blogDx[i] += (int)(stage.stageWidth / 2 - stage.mouseX) * 0.0001;
                    _blogDy[i] += (int)(stage.stageHeight / 2 - stage.mouseY) * 0.0001;
                }
                
                _blogPx[i] += _blogDx[i];
                _blogPy[i] += _blogDy[i];
                
                //跳ね返り時の処理
                if (_blogPx[i] < 0) {
                    _blogDx[i] = Math.random();
                }
                if (_blogPx[i] > _bmpData1.width) {
                    _blogDx[i] = -Math.random();
                }
                if (_blogPy[i] < 0) {
                    _blogDy[i] = Math.random();
                }
                if (_blogPy[i] > _bmpData1.height) {
                    _blogDy[i]=-Math.random();
                }
                
                //各ピクセルとビットマップのX位置との差の累乗 - 色の係数
                _vx[i] = new Array();
                for (x = 0; x < _bmpData1.width; x++) {
                    _vx[i][x] = int(Math.pow(_blogPx[i] - x, 2));
                }

                //各ピクセルとビットマップのY位置との差の累乗 - 色の係数
                _vy[i] = new Array();
                for (y = 0; y < _bmpData1.height; y++) {
                    _vy[i][y] = int(Math.pow(_blogPy[i] - y, 2));
                }
            }
            
            _bmpData1.lock();
            _bmpData2.lock();
            for (y = 0; y < _bmpData1.height; y++) {
                for (x = 0; x < _bmpData1.width; x++) {
                    var m:int = 1;
                    for (i = 0; i < _numBlobs; i++ ) {
                        //メタボボールの色係数
                        m += (60000 * (i + 2) * 2) / (_vy[i][y] + _vx[i][x] + 1);
                    }
                    
                    //各ピクセルの色を設定
                    r = Math.min(255, (m + y));
                    g = Math.min(255, (m + x));
                    b = Math.min(255, (x + m + y) / 2);
                    color = r << 16 | g << 8 | b;
                    
                    //ビットマップに設定
                    if (color < 0xffffff) {
                        _bmpData2.setPixel(x, y, color);    
                        _bmpData1.setPixel(x, y, color);
                    }
                }
            }
            //ぼかし(エッジのぎざぎざをなくすため)
            _bmpData1.applyFilter(_bmpData1, new Rectangle(0, 0, _bmpData1.width, _bmpData1.height), new Point(0,0), _blue);
            _bmpData1.unlock();
            _bmpData2.unlock();
        }
    }
}