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

WeaveSmoke

+ Code Clean Up & Reorganized to be more 'AS3 friendly'...
+ Optimizations & Tweaks
/**
 * Copyright FLASHMAFIA ( http://wonderfl.net/user/FLASHMAFIA )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/U3I3
 */

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;

    [SWF(width = '465', height = '465')]
    public class WeaveSmoke extends Sprite
    {
        private var bmd : BitmapData;
        private var silkContainer : Shape;
        private var sparksContainer : Shape;
        private var mx0 : Number;
        private var my0 : Number;
        private var pid : uint;
        private var silks : SilkRenderer;
        private var pressed : Boolean;

        function WeaveSmoke()
        {
            stage.stageFocusRect = tabChildren = tabEnabled = mouseChildren = mouseEnabled = false;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.MEDIUM;
            stage.frameRate = 32;
            opaqueBackground = 0x0;

            /* */

            bmd = new BitmapData(465, 465, false, 0x0);

            var bm : Bitmap = new Bitmap(bmd);
            addChild(bm);

            sparksContainer = new Shape();
            addChild(sparksContainer);

            silkContainer = new Shape();
            silks = new SilkRenderer(silkContainer, sparksContainer);

            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

            addEventListener(Event.ENTER_FRAME, oef);
        }

        private function oef(e : Event) : void
        {
            var mx : Number = (stage.mouseX % 465);
            var my : Number = (stage.mouseY % 465);

            if (pressed)
            {
                silks.addPoint(pid, mx, my, mx - mx0, my - my0);
            }
        
            sparksContainer.graphics.clear();
            silks.render();

            mx0 = mx;
            my0 = my;

            /* copy to bmd */

            bmd.draw(silkContainer, null, null, BlendMode.ADD);
            silkContainer.graphics.clear();
        }

        private function onMouseDown(e : MouseEvent) : void {
            pressed = true;
            pid = silks.add();
        }

        private function onMouseUp(e : MouseEvent) : void {
            pressed = false;

            if ((silks.slist[pid] != null) && !silks.slist[pid].completed)
            {
                silks.slist[pid].completed = true;
            }
        }
    }
}

import flash.display.Shape;
import flash.utils.ByteArray;


internal class SilkRenderer
{
    public var sparksContainer : Shape;
    public var silkContainer : Shape;
    public var slist : Vector.<Silk>;
    public var time : int;
    public var sparks : Sparks;

    public function SilkRenderer(silkContainer : Shape, sparksContainer : Shape)
    {
        this.silkContainer = silkContainer;
        this.sparksContainer = sparksContainer;
        slist = new Vector.<Silk>();
        sparks = new Sparks(256);
    }

    public function add() : uint
    {
        var slk : Silk = new Silk();
        slist.push(slk);
        return (slist.length - 1);
    }

    public function addPoint(id : uint, px : Number, py : Number, vx : Number, vy : Number) : void
    {
        var slk : Silk = this.slist[id];
        if (slk != null)
        {
            slk.add2(px, py, vx, vy);
        }
    }

    public function render() : int
    {
        for each (var slk : Silk in slist)
        {
            if (slk.alive) {
                sparks.addFromSilk(slk);

                var iter : uint = 4;
                while (iter-- != 0) {
                    slk.render(silkContainer);
                }

                slk.age++;
            }
        }

        sparks.render(sparksContainer);

        return time++;
    }
}

internal class PField
{
    protected var numP : uint;
    protected var start : int = 0;
    protected var end : int = 0;
    protected var plist : Vector.<Particle>;
    protected var drawStart : Function;
    protected var drawEnd : Function;

    public function PField(numP : uint)
    {
        this.numP = (numP != 0) ? numP : 256;
        plist = new Vector.<Particle>(this.numP, true);
    }

    public function getParticle() : Particle
    {
        return null;
    }

    public function render(shp : Shape) : void
    {
        for (; !(start == end || plist[start].alive);)
        {
            plist[start] = null;
            start = inc(start);
        }

        var func : Function = function(p : Particle) : void
        {
            p.px = p.x;
            p.py = p.y;
            p.age++;

            this['update'](p);
        };

        foreach(func);
        drawAll(shp);
    }

    public function drawAll(shp : Shape) : void
    {
        if (((drawStart != null) && drawStart(shp), this.foreach(function(p : Particle) : void {
            if (p.alive) this['draw'](p, shp);
        }))) {
        }
    }

    public function foreach(func : Function) : void
    {
        var n : int;
        for ((n = this.start); (n != this.end);) {
            func.call(this, this.plist[n]);
            n = this.inc(n);
        }
    }

    public function add(px : Number, py : Number) : Particle
    {
        var end : int = this.inc(this.end);
        this.start == end && (this.start = this.inc(this.start));

        var p : Particle = getParticle();
        p.x = px;
        p.y = py;

        this.plist[this.end] = p;
        this.end = end;

        return p;
    }

    public function inc(a : int) : int
    {
        return (a + 1) % this.numP;
    }

    public function dec(a : int) : int
    {
        return (a - 1) % this.numP;
    }
}

internal class Sparks extends PField {
    function Sparks(numP : uint) {
        super(numP);
    }

    override public function getParticle() : Particle {
        var p : Particle = new Particle();

        p.radius = 0.75;
        p.vx = -0.1 + 0.2 * Math.random();
        p.vy = -0.1 + 0.2 * Math.random();
        p.dieAt = 64;

        return p;
    }

    public function update(p : Particle) : void {
        p.x += p.vx;
        p.y += p.vy;

        var lum : Number = (p.age / p.dieAt);
        // p.a = (p.fadeIn == true) ? (p.maxA * Math.sin(3.141592653589793 * lum)) : lum;
        p.a = 0.5 + 0.5 * lum;

        p.alive = (p.age < p.dieAt);
    }

    public function draw(p : Particle, shp : Shape) : void {
        if (p.alive) {
            var col : uint = ((p.r & 0xFF) << 16) + ((p.g & 0xFF) << 8) + (p.b & 0xFF);

            shp.graphics.beginFill(col, p.a);
            shp.graphics.drawCircle(p.x, p.y, p.radius);
            shp.graphics.endFill();
        }
    }

    public function addFromSilk(a : Silk) : void {
        var sparks : Sparks = this;

        a.foreach(function(p : Particle) : void {
            if (0.03 > Math.random()) {
                p = sparks.add(p.x, p.y);
                p.r = a.sparkR;
                p.g = a.sparkG;
                p.b = a.sparkB;
            }
        });
    }
}

internal class Silk extends PField {
    /* */
    public const noiseOctaves : int = 8;
    public const noiseFallout : Number = 0.65;
    public const noiseScale : Number = 0.01;
    public const mouseDamp : Number = 0.2;
    /* */
    public var colR : uint = 0x80;
    public var colG : uint = 0x7E;
    public var colB : uint = 0x78;
    public var sparkR : uint = 0x80;
    public var sparkG : uint = 0x7E;
    public var sparkB : uint = 0x78;
    public var opacity : Number = 0.07;
    /* */
    public var age : int = 0;
    public var completed : Boolean = false;
    public var alive : Boolean = true;
    public var seed : Number = -(0.008 / 2) * Math.random();
    public var perlin : PerlinNoise = new PerlinNoise(0);
    /* */
    private var p0 : Particle;

    public function Silk() {
        super(32);

        drawStart = drawStartX;
        drawEnd = drawEndX;

        Noise.octaves = noiseOctaves;
        Noise.fallout = noiseFallout;
    }

    override public function getParticle() : Particle {
        var p : Particle = new Particle();

        p.death = 128;

        p.x = 0.0;
        p.y = 0.0;
        p.px = 0.0;
        p.py = 0.0;
        p.vmx = 0.0;
        p.vmy = 0.0;
        p.accx = 0.0;
        p.accy = 0.0;

        p.friction = 0.975;
        p.mass = 1.0;
        p.springLen = 0.0;
        p.rigidity = 0.3;
        p.radius = 0.75;

        p.r = 0xFF;
        p.g = 0xFF;
        p.b = 0xFF;

        p.vx = -0.1 + 0.2 * Math.random();
        p.vy = -0.1 + 0.2 * Math.random();

        return p;
    }

    public function add2(px : Number, py : Number, vx : Number, vy : Number) : Particle {
        var f : Boolean = (this.start == this.end);
        var p : Particle = super.add(px, py);
        if (f == false) this.p0.next = p;

        var damp : Number = this.mouseDamp;
        p.vmx = vx * damp;
        p.vmy = vy * damp;

        return (this.p0 = p);
    }

    override public function render(a : Shape) : void {
        super.render(a);

        this.opacity -= 0.000005;
        if ((this.completed == true) && (this.opacity < 0.0001)) {
            this.alive = false;
        }
    }

    public function update(p : Particle) : Boolean {
        var ang : Number = 2 * (3.141592653589793 * 2) * Noise.gen(p.x * noiseScale, p.y * noiseScale, seed + 0.008 * age, perlin);
        ang *= 2;

        if (p.vmx != 0) p.vmx = 0.0001;
        if (p.vmy != 0) p.vmy = 0.0001;
        ang += (Math.atan2(p.vmx, p.vmy));

        addAngleForce(p, ang + (3.141592653589793 / 2), 0.5);

        addForce(p, p.vmx, p.vmy);

        p.vmx *= 0.99;
        p.vmy *= 0.99;
        p.rigidity *= 0.999;

        if (p.next != null) {
            /* move */

            p.x += (p.x - p.px) * p.friction + p.accx;
            p.y += (p.y - p.py) * p.friction + p.accy;
            p.accx = 0.0;
            p.accy = 0.0;

            /* constrain */

            var dx : Number = p.next.x - p.x;
            var dy : Number = p.next.y - p.y;
            var d : Number = Math.sqrt(dx * dx + dy * dy);

            d = 1 - (p.springLen / d);
            dx = p.rigidity * dx * d;
            dy = p.rigidity * dy * d;

            this.addVelo(p, dx, dy);

            if ((d > 0.001) && (p.next.next != null)) {
                this.addVelo(p.next, -dx, -dy);
            }
        }

        p.alive = (p.age < p.death);

        return p.alive;
    }

    private function addForce(p : Particle, fx : Number, fy : Number) : void {
        p.accx += fx / p.mass;
        p.accy += fy / p.mass;
    }

    private function addAngleForce(p : Particle, fx : Number, fy : Number) : void {
        fy /= p.mass;
        p.accx += fy * Math.cos(fx);
        p.accy += fy * Math.sin(fx);
    }

    private function addVelo(p : Particle, vx : Number, vy : Number) : void {
        p.x += vx;
        p.y += vy;
    }

    public function drawStartX(sh : Shape) : void {
        sh.graphics.lineStyle(1.0, (((colR & 0xFF) << 16) + ((colG & 0xFF) << 8) + (colB & 0xFF)), opacity, false, 'none', 'none');

        var p : Particle = plist[start];
        if (p != null) sh.graphics.moveTo(p.x, p.y);
    }

    public function draw(p : Particle, sh : Shape) : void {
        var pnxt : Particle = p.next;
        if (pnxt != null) {
            sh.graphics.curveTo(p.x, p.y, (p.x + pnxt.x) / 2, (p.y + pnxt.y) / 2);
        }
    }

    public function drawEndX(a : Shape) : void {
    }
}

internal class Particle {
    public var next : Particle;
    public var age : int = 0;
    public var death : int = 64;
    public var alive : Boolean = true;
    public var px : Number = 0.0;
    public var py : Number = 0.0;
    public var x : Number = 0.0;
    public var y : Number = 0.0;
    public var vmx : Number = 0.0;
    public var vmy : Number = 0.0;
    public var accx : Number = 0.0;
    public var accy : Number = 0.0;
    public var friction : Number = 0.975;
    public var mass : Number = 1.0;
    public var springLen : Number = 0.0;
    public var rigidity : Number = 0.3;
    public var a : Number = 0.75;
    public var r : uint = 0xFF;
    public var g : uint = 0xFF;
    public var b : uint = 0xFF;
    public var radius : Number = 0.75;
    public var vx : Number = -1 + 2 * Math.random();
    public var vy : Number = -1 + 1 * Math.random();
    public var dieAt : int = 25;
}

internal class PerlinNoise {
    private var perm : ByteArray;

    function PerlinNoise(seed : Number) {
        var rnd : Marsaglia = (!isNaN(seed) ? new Marsaglia(seed, 0) : Marsaglia.createRandomized());
        var i : int;
        var j : int;

        perm = new ByteArray();
        perm.length = 512;

        for (i = 0; i < 256; ++i) {
            perm[i] = i;
        }
        for (i = 0; i < 256; ++i) {
            var t : int = perm[j = rnd.nextInt() & 0xFF];
            perm[j] = perm[i];
            perm[i] = t;
        }
        for (i = 0; i < 256; ++i) {
            perm[i + 256] = perm[i];
        }
    }

    public function noise3d(x : Number, y : Number, z : Number) : Number {
        var X : int = (x | 0) & 255, Y : int = (y | 0) & 255, Z : int = (z | 0) & 255;
        x -= (x | 0);
        y -= (y | 0);
        z -= (z | 0);
        var fx : Number = (3 - 2 * x) * x * x, fy : Number = (3 - 2 * y) * y * y, fz : Number = (3 - 2 * z) * z * z;
        var p0 : int = perm[X] + Y, p00 : int = perm[p0] + Z, p01 : int = perm[p0 + 1] + Z, p1 : int = perm[X + 1] + Y, p10 : int = perm[p1] + Z, p11 : int = perm[p1 + 1] + Z;
        return lerp(fz, lerp(fy, lerp(fx, grad3d(perm[p00], x, y, z), grad3d(perm[p10], x - 1, y, z)), lerp(fx, grad3d(perm[p01], x, y - 1, z), grad3d(perm[p11], x - 1, y - 1, z))), lerp(fy, lerp(fx, grad3d(perm[p00 + 1], x, y, z - 1), grad3d(perm[p10 + 1], x - 1, y, z - 1)), lerp(fx, grad3d(perm[p01 + 1], x, y - 1, z - 1), grad3d(perm[p11 + 1], x - 1, y - 1, z - 1))));
    }

    public function noise2d(x : Number, y : Number) : Number {
        var X : int = Math.floor(x) & 255;
        var Y : int = Math.floor(y) & 255;

        x -= Math.floor(x);
        y -= Math.floor(y);

        var fx : Number = (3 - 2 * x) * x * x, fy : Number = (3 - 2 * y) * y * y;
        var p0 : Number = perm[X] + Y, p1 : Number = perm[X + 1] + Y;

        return lerp(fy, lerp(fx, grad2d(perm[p0], x, y), grad2d(perm[p1], x - 1, y)), lerp(fx, grad2d(perm[p0 + 1], x, y - 1), grad2d(perm[p1 + 1], x - 1, y - 1)));
    }

    public function noise1d(x : Number) : Number {
        var X : int = Math.floor(x) & 255;

        x -= Math.floor(x);

        var fx : Number = (3 - 2 * x) * x * x;

        return lerp(fx, grad1d(perm[X], x), grad1d(perm[X + 1], x - 1));
    }

    public function grad3d(i : int, x : Number, y : Number, z : Number) : Number {
        var h : int = i & 15;

        switch (h & 0xF) {
            case 0x0:
                return x + y;
            case 0x1:
                return -x + y;
            case 0x2:
                return x - y;
            case 0x3:
                return -x - y;
            case 0x4:
                return x + z;
            case 0x5:
                return -x + z;
            case 0x6:
                return x - z;
            case 0x7:
                return -x - z;
            case 0x8:
                return y + z;
            case 0x9:
                return -y + z;
            case 0xA:
                return y - z;
            case 0xB:
                return -y - z;
            case 0xC:
                return y + x;
            case 0xD:
                return -y + z;
            case 0xE:
                return y - x;
            case 0xF:
                return -y - z;
        }
        return 0;
    }

    public function grad2d(i : int, x : Number, y : Number) : Number {
        var v : Number = (i & 1) == 0 ? x : y;
        return (i & 2) == 0 ? -v : v;
    }

    public function grad1d(i : int, x : Number) : Number {
        return (i & 1) == 0 ? -x : x;
    }

    public function lerp(t : Number, a : Number, b : Number) : Number {
        return a + t * (b - a);
    }
}

internal class Marsaglia {
    private var z : int;
    private var w : int;

    public function Marsaglia(i1 : Number, i2 : Number) {
        z = i1 || 362436069;
        w = i2 || 521288629;
    }

    public function nextInt() : int {
        z = (36969 * (z & 65535) + (z >>> 16)) & 0xFFFFFFFF;
        w = (18000 * (w & 65535) + (w >>> 16)) & 0xFFFFFFFF;
        return (((z & 0xFFFF) << 16) | (w & 0xFFFF)) & 0xFFFFFFFF;
    }

    public function nextDouble() : Number {
        var i : Number = nextInt() / 4294967296.0;
        return i < 0 ? 1 + i : i;
    }

    public static function createRandomized() : Marsaglia {
        var now : int = new Date().getTime();
        return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF);
    }
}

internal class Noise {
    public static var octaves : int = 4;
    public static var fallout : Number = 0.5;
    public static var seed : Number = 2222;

    public static function gen(x : Number, y : Number, z : Number, generator : PerlinNoise) : Number {
        var effect : Number = 1;
        var k : Number = 1;
        var sum : Number = 0;

        for (var i : int = 0; i < octaves; ++i) {
            effect *= fallout;
            sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2;
            k *= 2;
        }

        return sum;
    }
}