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

flash on 2015-5-30

Fluid \ Learning \ Processing 1.0

http://www.processing.org/learning/topics/fluid.html

via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding

http://violentcoding.com/blog/2008/07/26/archives/135
Get Adobe Flash player
by dahex 30 May 2015
    Embed
/**
 * Copyright dahex ( http://wonderfl.net/user/dahex )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/s0pc
 */

// forked from mio_____'s forked from: 流体パーティクル(解読用)

// forked from clockmaker's 流体パーティクル(解読用)

// forked from miniapp's 流体パーティクル

/**

 * Fluid \ Learning \ Processing 1.0

 * http://www.processing.org/learning/topics/fluid.html

 * 

 * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding

 * http://violentcoding.com/blog/2008/07/26/archives/135

 */

package {

    import flash.display.Shape;

    import flash.display.Bitmap;

    import flash.display.BitmapData;

    import flash.display.Sprite;

    import flash.display.StageAlign;

    import flash.display.StageQuality;

    import flash.display.StageScaleMode;

    import flash.events.Event;

    import flash.events.MouseEvent;

    import flash.geom.ColorTransform;

    import flash.geom.Rectangle;



    

    [SWF(backgroundColor=0x000000, width=465, height=465, frameRate=60)]

    public class FluidLine extends Sprite {

        

        public function FluidLine() {

            if (stage) init();

            else addEventListener(Event.ADDED_TO_STAGE, init);

        }

        

        private var pmouseX:Number;

        private var pmouseY:Number;

        private var canvasWidth:int = 465;

        private var canvasHeight:int = 465;

        private var mousePressed:Boolean = true;

        private var resolution:int = 50;

        private var penSize:int = 40;

        private var numCols:int = canvasWidth / resolution;;

        private var numRows:int = canvasHeight / resolution;

        private var numParticles:int = 10000;

        private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();

        private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);

        private var pcount:int = 0;

        private var arrows:Array = [];

        

        private function init(e:Event = null):void {

            removeEventListener(Event.ADDED_TO_STAGE, init);

            stage.scaleMode = StageScaleMode.NO_SCALE;

            stage.align = StageAlign.TOP_LEFT;

            opaqueBackground = 0x0;

            

            

            stage.quality = StageQuality.LOW;

 

            

            for (var i:int = 0; i < numParticles; i++) {

                particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);

            }

            

            for (var col:int = 0; col < numCols; ++col) { 

                gridDatasVectors[col] = new Vector.<GridData>(numRows, true);

                arrows[col] = [];

                for (var row:int = 0; row < numRows; ++row) { 

                    var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);

                    gridData.col = col;

                    gridData.row = row;

                    gridDatasVectors[col][row] = gridData;

                    

                    var arrow:Arrow = new Arrow();

                    addChild(arrow);

                    arrows[col][row] = arrow;

                }

            }

            

                        

            var gridView:Shape = new Shape();

            gridView.graphics.beginFill(0x808080);

            addChild(gridView);

            for (col = 0; col <= numCols; ++col) {

                gridView.graphics.drawRect(0, col * resolution, canvasWidth, 1);

            }

            for (row = 0; row <= numRows; ++row) { 

                gridView.graphics.drawRect(row * resolution, 0, 1, canvasHeight);

            }

            

            //隣接するグリッドをセットしていく。

            for (col = 0; col < numCols; ++col) { 

                for (row = 0; row < numRows; ++row) { 

                    gridData = gridDatasVectors[col][row];

                    if (row > 0) {

                        var up:GridData = gridDatasVectors[col][row - 1];//上

                        gridData.up = up;

                        up.low = gridData;//下

                    }

                    

                    if (col > 0) {

                        var left:GridData = gridDatasVectors[col - 1][row];//左

                        gridData.left = left;

                        left.right = gridData;//右

                    }

                    

                    if (row > 0 && col > 0) {

                        var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];

                        gridData.upperLeft = upperLeft;

                        upperLeft.lowerRight = gridData;

                    }

                    

                    if (row > 0 && col < numCols - 1) {

                        var upperRight:GridData = gridDatasVectors[col + 1][row - 1];

                        gridData.upperRight = upperRight;

                        upperRight.lowerLeft = gridData;

                    }

                }

            }

            

            gridDatasVectors.fixed = true;

            addEventListener(Event.ENTER_FRAME, draw);

        }

        

        private function draw(e:Event):void {

            var mouseXvel:Number = mouseX - pmouseX;

            var mouseYvel:Number = mouseY - pmouseY;

            

            for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {

                for each(var gridData:GridData in gridDatas) {

                    if (mousePressed) {

                        updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);

                    }

                    updatePressure(gridData);

                    

                }

            }

            

            graphics.clear();

            graphics.lineStyle(1, 0xFFFFFF, 0.4);

            updateParticle();

            

            for each(gridDatas in gridDatasVectors) {

                for each(gridData in gridDatas) {

                    apdateVelocity(gridData);

                }

            }

            

            pmouseX = mouseX;

            pmouseY = mouseY;

        }

        

        public function updateParticle():void {

            for each(var p:Particle in particles) {

                if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {

                    var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける

                    var row:int = int(p.y / resolution);

                    

                    if (col > numCols - 1) col = numCols - 1;

                    if (row > numRows - 1) row = numRows - 1;

                    

                    var gridData:GridData = gridDatasVectors[col][row];

                    

                    var ax:Number = (p.x % resolution) / resolution;

                    var ay:Number = (p.y % resolution) / resolution;

                    p.xvel += (1 - ax) * gridData.xvel * 0.05;

                    p.yvel += (1 - ay) * gridData.yvel * 0.05;

                    

                    p.xvel += ax * gridData.right.xvel * 0.05;

                    p.yvel += ax * gridData.right.yvel * 0.05;

                    

                    p.xvel += ay * gridData.low.xvel * 0.05;

                    p.yvel += ay * gridData.low.yvel * 0.05;

                    

                    p.x += p.xvel;

                    p.y += p.yvel;

                    

                    var dx:Number = p.px - p.x;

                    var dy:Number = p.py - p.y;

                    var dist:Number = Math.sqrt(dx * dx + dy * dy);

                    var limit:Number = Math.random() * 0.5;

                    

                    if (dist > limit) {

                        graphics.moveTo(p.x, p.y);

                        graphics.lineTo(p.px, p.py);

                    }

                    else {

                        graphics.moveTo(p.x, p.y);

                        graphics.lineTo(p.x + limit, p.y + limit);

                    }

                    

                    p.px = p.x;

                    p.py = p.y;

                }

                else {

                    p.x = p.px = Math.random() * canvasWidth;

                    p.y = p.py = Math.random() * canvasHeight;

                    p.xvel = 0;

                    p.yvel = 0;

                }

                

                p.xvel *= 0.5;

                p.yvel *= 0.5;

            }

        }

        

        /**

         * マウスドラッグの処理

         * @param    gridData

         * @param    mvelX

         * @param    mvelY

         * @param    penSize

         */

        public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {

            var dx:Number = gridData.x - mouseX;

            var dy:Number = gridData.y - mouseY;

            var dist:Number = Math.sqrt(dy * dy + dx * dx);

            

            if (dist < penSize) { 

                if (dist < 4) {

                    dist = penSize;

                }

                

                //マウスに近いほど力が強くなるように。

                var power:Number = penSize / dist;

                gridData.xvel += mvelX * power;

                gridData.yvel += mvelY * power;

            }

        }

        

        public function updatePressure(gridData:GridData):void {

            var pressureX:Number = (

                  gridData.upperLeft.xvel * 0.5 //左上

                + gridData.left.xvel       //左

                + gridData.lowerLeft.xvel * 0.5 //左下

                - gridData.upperRight.xvel * 0.5 //右上

                - gridData.right.xvel       //右

                - gridData.lowerRight.xvel * 0.5 //右下

            );

            

            var pressureY:Number = (

                  gridData.upperLeft.yvel * 0.5 //左上

                + gridData.up.yvel       //上

                + gridData.upperRight.yvel * 0.5 //右上

                - gridData.lowerLeft.yvel * 0.5 //左下

                - gridData.low.yvel       //下

                - gridData.lowerRight.yvel * 0.5 //右下

            );

            

            gridData.pressure = (pressureX + pressureY) * 0.25;

            

            

            var arrow:Arrow = arrows[gridData.col][gridData.row];

            arrow.x = gridData.x + resolution / 2 >> 0;

            arrow.y = gridData.y + resolution / 2 >> 0;

            arrow.rotation = Math.atan2(gridData.yvel, gridData.xvel) * 180 / Math.PI;

            arrow.scaleX = arrow.scaleY = Math.sqrt(gridData.yvel * gridData.yvel + gridData.xvel * gridData.xvel) / 100

        }

        

        public function apdateVelocity(gridData:GridData):void {

            gridData.xvel += (

                  gridData.upperLeft.pressure * 0.5 //左上

                + gridData.left.pressure       //左

                + gridData.lowerLeft.pressure * 0.5 //左下

                - gridData.upperRight.pressure * 0.5 //右上

                - gridData.right.pressure       //右

                - gridData.lowerRight.pressure * 0.5 //右下

            ) * 0.25;

            

            gridData.yvel += (

                  gridData.upperLeft.pressure * 0.5 //左上

                + gridData.up.pressure       //上

                + gridData.upperRight.pressure * 0.5 //右上

                - gridData.lowerLeft.pressure * 0.5 //左下

                - gridData.low.pressure       //下

                - gridData.lowerRight.pressure * 0.5 //右下

            ) * 0.25;

            

            gridData.xvel *= 0.99;

            gridData.yvel *= 0.99;

        }

        

    }    

}







import flash.geom.Rectangle;

class BaseGridData {

    

    public var col:int = 0;

    public var row:int = 0;

    

    public var x:int = 0;

    public var y:int = 0;

    

    public var xvel:Number = 0;

    public var yvel:Number = 0;

    

    public var pressure:Number = 0;

    

    public var color:Number = 0;

    public var rgb:uint;

    public var rectangle:Rectangle;

}



class GridData extends BaseGridData{

    

    public function GridData(x:int, y:int, resolution:Number) {

        this.x = x;

        this.y = y;

        rectangle = new Rectangle(x, y, resolution, resolution)

    }

    

    //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、

    //空のデータをセットしておく。

    public var upperLeft:BaseGridData = new NullGridData();//左上

    public var up:BaseGridData = new NullGridData();//上

    public var upperRight:BaseGridData = new NullGridData();//右上

    

    public var left:BaseGridData = new NullGridData();//左

    public var right:BaseGridData = new NullGridData();//右

    

    public var lowerLeft:BaseGridData = new NullGridData();//左下

    public var low:BaseGridData = new NullGridData();//下

    public var lowerRight:BaseGridData = new NullGridData();//右下    

}



class NullGridData extends BaseGridData{

}



class Particle {    

    

    public function Particle(x:Number, y:Number) {

        this.x = px = x;

        this.y = py = y;

    }

    

    public var x:Number;

    public var y:Number;

    

    public var px:Number;

    public var py:Number;

    public var xvel:Number = 0;

    public var yvel:Number = 0;

    

}



import flash.display.*;

class Arrow extends Sprite

{

    function Arrow() {

        var s:Shape = new Shape();

        s.graphics.beginFill(0xFFFFFF, 1);

        s.graphics.moveTo(2, 4);

        s.graphics.lineTo(8, 4);

        s.graphics.lineTo(8, 0);

        s.graphics.lineTo(20, 7);

        s.graphics.lineTo(8, 14);

        s.graphics.lineTo(8, 10);

        s.graphics.lineTo(2, 10);

        s.graphics.lineTo(2, 4);

        

        s.x = -10;

        s.y = -7;

        addChild(s);

    }

}