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

forked from: bubble sort

bubble sorting visualization.
inspired on http://wonderfl.net/c/8rbD
for Universidade Federal de Itajubá - Campus Itabira
git https://github.com/thyfl/eco-010/tree/master/fabiana/extras/bubble (11 november 2011, now its colored. but still not ready)
Get Adobe Flash player
by Thy 12 Nov 2011
/**
 * Copyright Thy ( http://wonderfl.net/user/Thy )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kGYT
 */

package 
{
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    
    /**
     * bubble sorting visualization.
     * inspired on http://wonderfl.net/c/8rbD
     * for Universidade Federal de Itajubá - Campus Itabira
     * git https://github.com/thyfl/eco-010/tree/master/fabiana/extras/bubble (11 november 2011, now its colored. but still not ready)
     * @author thi
     * 
     * 
     * TODO: environment blubbles force map
     * TODO: environment blubbles proper reposition on zooming/resizing
     * TODO: full screen button
     * 
     */
    public class Main extends Sprite 
    {
        public function Main():void 
        {
            // setup
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
                stage.frameRate = 40;
            
            // children
                this.addChild(ground.back); // background
                this.addChild(bubbles.bubbles); // bubbles
                this.addChild(text); // input
                this.addChild(text2); // result
                this.addChild(ground.front); // foreground
            
            // event
                this.addEventListener(Event.ENTER_FRAME, ef);
                stage.addEventListener(Event.RESIZE, resize);
            
            // var
                s = text.tf.text;
            
            // init
                resize();
                // bubbles
                bubbles.init(s, radius);
                bubbles.bubbles.y = 20; // user's bubbles
                // text
                stage.focus = text.tf;
                text.tf.setSelection(0, text.tf.text.length);
                text.x = text.y = text2.x = 0; // text
                
            // ground bubbles
                groundBubblesInit();
        }
        
        // 
        private var ground:Ground = new Ground(), // background, foreground
                    //
                    bubbles:Bubbles = new Bubbles(), // bubble's list's list
                    backBubbles:Bubbles = new Bubbles(),
                    frontBubbles:Bubbles = new Bubbles(),
                    //
                    s:String = "",
                    text:Field = new Field(), // input text
                    text2:Field = new Field(), // sorted text
                    //
                    W:Number = 0, 
                    H:Number = 0,
                    radius:Number = Math.PI * .75; // radius from an sphere's volume input
                    
                    
        private function groundBubblesInit():void
        {
            // create background and foreground bubbles
            var i:int = -1, bs:Bubbles = backBubbles, s:String;
            while (++i < 5)
            {
                bs.next = new Bubbles();
                bs = bs.next;
                ground.back.addChild(bs.bubbles);
                s = String(int(Math.random() * Math.random() * 1000));
                bs.init(s, radius);
                bs.bubbles.y = 0;
                bs.bubbles.x = -20;
            }
            i = -1;
            bs = frontBubbles;
            while (++i < 5)
            {
                bs.next = new Bubbles();
                bs = bs.next;
                ground.front.addChild(bs.bubbles);
                s = String(int(Math.random() * Math.random() * 1000));
                bs.init(s, radius);
                bs.bubbles.y = 0;
                bs.bubbles.x = -20;
            }    
        }
        
        private function resize(e:Event = null):void 
        {
            
            // app dimension
                W = stage.stageWidth;
                H = stage.stageHeight;
            
            // texts
                text.resize(W, H);
                text2.resize(W, H);
                text2.y = H - 20;
            
            // ground
                ground.resize(W,H);
            
            // bubbles
                var b:Bubbles = bubbles;
                b.bubbles.x = W / 2;
                /*
                b = backBubbles;
                while (b = b.next)
                {
                    b.bubbles.x = W / 2;
                }
                b = frontBubbles;
                while (b = b.next)
                {
                    b.bubbles.x = W / 2;
                }
                */
        }
        
        private function ef(e:Event):void 
        {
            // re init user's bubbles
            if (s != text.tf.text && ++text.time > text.timeOut)
            {
                text.time = 0;
                s = text.tf.text;
                if (s == "") s = "1";
                bubbles.init(s, radius);
            }
            
            var b:Bubbles = bubbles;
            // move & sort user's bubbles
            text2.tf.text = b.sort(); // user's
            var zoom:Number = b.zoom(W, H); // adjust the bubbles zooming
            
            var dx:Number, dy:Number, s2:String, offset:Number;
            // move & sort back/foreground bubbles
            b = backBubbles;
            while (b = b.next)
            {
                b.sort();
                b.apllyZoom(zoom);
                dx = Math.random() - .5;
                dy = -10;
                if (!b.move(W, H, dx, dy))
                {
                    s2 = String(int(Math.random() * Math.random() * 1000));
                    offset = Math.random();
                    b.replace(W, H, s2, radius, offset);
                }
            }
            b = frontBubbles;
            while (b = b.next)
            {
                b.sort();
                b.apllyZoom(zoom);
                dx = Math.random() - .5;
                dy = -10;
                if (!b.move(W, H, dx, dy))
                {
                    s2 = String(int(Math.random() * Math.random() * 1000));
                    offset = Math.random() * Math.random() * 2;
                    b.replace(W, H, s2, radius/8, offset*8);
                }
            }
            
            
        }
        
    }
    
}



import flash.filters.BlurFilter;
/**
 * bubble list
 * @author thi
 */
class Bubbles 
{
    public var next:Bubbles,
               bubbles:Bubble = new Bubble(), // head
               garbage:Bubble = new Bubble(), // head
               //
               rMultiplier:Number, 
               rOffset:Number;
    
    public function Bubbles(rm:Number = 1, ro:Number = 1) 
    {
        rMultiplier = rm;
        rOffset = ro;
    }
    
    //                                     radius multiplier, radius offset
    public function init(s:String = "1", rm:Number = 1, ro:Number = 1):void
    {
        rMultiplier = rm;
        rOffset = ro;
        
        var b:Bubble = bubbles,
            b2:Bubble = bubbles,
            i:int = -1,
            l:int = s.length;
            
        // modify bubbles
        while ((b = b.next) !== null && ++i < l)
            b2 = b.draw(Number(s.charAt(i)), rMultiplier, rOffset);
        b = b2; // b is the last modified bubble
        
        // recycle bubbles
        b2 = garbage;
        while (++i < l && (b2 = b2.next) !== null)
        {
            garbage.next = b2.next;
            b2.next = null;
            b2.prev = b;
            bubbles.addChild(b2.draw(Number(s.charAt(i)), rMultiplier, rOffset));
            b.next = b2;
            b = b.next;
        }
        --i;
        // b is the last modified bubble
        
        // create bubbles
        while (++i < l)
        {
            b.next = new Bubble();
            b.next.prev = b;
            b = b.next.draw(Number(s.charAt(i)), rMultiplier, rOffset);
            bubbles.addChild(b);
        }
        --i;
        // b is the newest or last modified bubble
        
        // add bubbles to garbage, prev pointer ignored
        if (i == l)
        {
            var b3:Bubble = b2 = b;
            while ((b2 = b2.next) !== null)
            {
                bubbles.removeChild(b2.clear());
                b3 = b2; // last cleared
            }
            b3.next = garbage.next;
            garbage.next = b.next;
            b.next = null;
        }
        
        bubbles.next.prev = null; // dont need to go back to head, when backwards
    } // init
    
    public function sort():String
    {
        var b:Bubble = bubbles,
            //b2:Bubble, // hold last bubble
            next:Bubble,
            s:String = "";
        
        // get the angle for the movement right
        while ((b = b.next) !== null)
        {
            // finish when we got to the last bubble
            if ((next = b.next) === null)
                break;
            
            s += String(b.info); // sorted string
            
            // you shall not pass
            if (next.info >= b.info)
            {
                b.passing = false;
                b.teta *= .2;
                continue;
            }
            
            // shall pass
            {
                b.passing = true;
                
                // now the angle
                b.teta += next.radius / b.radius * .04 + b.teta * .2;
                //b.teta += .1;
                if (next.passing && next.next)
                    b.teta *= 0.8;
                
                // already passed
                if (b.teta > Math.PI)
                {
                    //b.teta *= 0.1;
                    //b.teta = 0;
                    // pointer mess
                    next.prev = b.prev;
                    b.prev = next;
                    b.next = next.next;
                    next.next = b;
                    // (now works like like b is next; next is b)
                    if (next.prev === null)
                        bubbles.next = next;
                    else
                        next.prev.next = next;
                    if (b.next)
                        b.next.prev = b;
                    else
                        b = next;
                }
            }
        } // while's angle stuff
        s += String(b.info); // last char
        _upper = b; // b is the last/up bubble; _upper is used on zooming
        
        // adjust the upper bubble position
        b.x = 0;
        b.y = b.radius;
        
        // move the bubbles
        while (b = b.prev)
        {
            next = b.next;
            
            // passing
            if (b.passing)
            {
                var r:Number = (next.radius + b.radius) / 2; // average radius
                var xc:Number = (b.x + next.x) / 2; // x center
                var yc:Number = (b.y + next.y) / 2; // y center
                var sin:Number = Math.sin(b.teta) * r;
                var cos:Number = Math.cos(b.teta) * r;
                
                b.x = xc + sin;
                b.y = yc + cos;
                
                // move the next bubble
                if (next.next)
                {
                    next.x = xc - sin;
                    next.y = yc - cos;
                    continue;
                }
                
                // move only a little, the last/upper bubble
                {
                    next.x += (xc - sin - next.x) * .1;
                    next.y += (yc - cos - next.y) * .1;
                }
                continue;
            }
            
            // not passing
            {
                b.x += (next.x - b.x ) * .7 + Math.random() * 1 - .5;
                b.y += (next.y + next.radius + b.radius - b.y ) * .7;
            }
        } // while's movement stuff
        return s;
    } // sort
    
    // adjust the bubbles zoom
    private var _upper:Bubble;
    public function zoom(W:Number, H:Number):Number
    {
        // TODO? fix the width.. bug dont looks bad.
        var _y:Number = _upper.height + 5;
        var _h:Number = (bubbles.height + _y) / bubbles.scaleY;
        var min:Number = Math.min(W / bubbles.width, (H - _y) / _h);
        bubbles.scaleX = bubbles.scaleY += (min - bubbles.scaleY) * .2;
        return bubbles.scaleY;
    }
    
    // now functions for automatic bubbles -----------------------------------------------
    
    public function apllyZoom(zoom:Number):void
    {
        bubbles.scaleX = bubbles.scaleY = zoom;
    }
    
    private var blur:BlurFilter = new BlurFilter(0, 0, 1);
    public var upSpeed:Number; // TODO: maybe use that instead the forceMap
    public function move(W:Number, H:Number, dx:Number, dy:Number):Boolean
    {
        // move the bubble
        bubbles.x += dx * rOffset;
        bubbles.y += dy * rOffset;
        dx = bubbles.x - W/2;
        dy = bubbles.y - H / 2;
        dy *= .75;
        dx *= 1;
        
        // apply blur
        blur.blurX = blur.blurY = Math.sqrt(dx * dx + dy*dy) * .05 + rOffset*2;
        bubbles.filters = [blur];
        
        if (bubbles.x > W + 20 || bubbles.x < -20 || bubbles.y < -bubbles.height - 20)
            return false;
        return true;
    }
    
    public function replace(W:Number, H:Number, s:String, rm:Number = 1, ro:Number = 1):void
    {
        init(s, rm, ro);
        bubbles.x = Math.random() * W;
        bubbles.y = H + bubbles.height + 20;
    }
    
}



import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.filters.GlowFilter;
/**
 * blub.
 * TODO: make it pretty.
 * @author thi
 */
class Bubble extends Sprite
{
    public var next:Bubble,
               prev:Bubble,
               //
               info:Number, // the sphere's volume
               radius:Number,
               teta:Number = 0, // the movement
               passing:Boolean; // if going up
    
    public function Bubble() 
    {
        //var glow:GlowFilter = new GlowFilter(0x707090, 1, 6, 6, 5, 3, false, false);
        //this.filters = [glow];
        //this.blendMode = BlendMode.HARDLIGHT;
    }
    
    // vector without bmData's cpyPixel
    public function draw(info:Number, rm:Number, ro:Number):Bubble
    {
        // information
        this.info = info;
        radius = rm * info * ro;
        
        // draw it
        var g:Graphics = this.graphics;
        g.clear();
        //g.lineStyle(.5 , 0xFFFFFF, .1);
        g.beginFill(0xD0E0F0, .4);
        g.drawCircle(0, 0, radius);
        g.endFill();
        g = null;
        
        return this;
    }
    
    public function clear():Bubble
    {
        this.graphics.clear();
        return this;
    }
    
}



import flash.display.Graphics;
import flash.display.Sprite;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
/**
 * back/fore ground.
 * @author thi
 */
class Ground 
{
    public var back:Sprite,
               front:Sprite;
    
    public function Ground() 
    {
        back = new Sprite();
        front = new Sprite();
        back.cacheAsBitmap = true;
        front.cacheAsBitmap = true;
    }
    
    public function resize(W:Number, H:Number):void
    {
        var g:Graphics = back.graphics;
        g.clear();
        g.moveTo(0, 0);
        
        var colors:Array = [0xC4E6F5, 0x435268];
        var alphas:Array = [1, 1];
        var ratios:Array = [0, 255];
        var matrix:Matrix = new Matrix();
        matrix.createGradientBox(W, H, 90*Math.PI/180, 0, 0);
        g.beginGradientFill("linear", colors, alphas, ratios, matrix);
        g.drawRect(0, 0, W, H);
        g.endFill();
        
        var glow:GlowFilter = new GlowFilter(0, .3, 256, 296, 1, 2, true);
        back.filters = [glow];
        
        
    }
    
}



import flash.display.Graphics;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
/**
 * input/output textfield
 * @author thi
 */
class Field extends Sprite
{
    public var time:int = 0,
               timeOut:int = 30,
               tf:TextField;
    private var g:Graphics;
    
    public function Field() 
    {
        var f:TextFormat = new TextFormat("Arial", 14);
        tf = new TextField();
        tf.defaultTextFormat = f;
        tf.type = "input";
        tf.text = "9991232387418521";
        //tf.text = "231232938741895211111111111111111111111111111111111111111111111";
        //tf.text = "11111111111111119999999999999999911111111111111111111199999999999991111111111111111999999999999911111111111119999999999999111111111999999999991111111111111";
        tf.textColor = 0xFFFFFF;
        tf.height = 20;
        tf.multiline = false;
        this.addChild(tf);
        
        // debug
        tf.border = true;
    }
    
    public function resize(W:Number, H:Number):void
    {
        // text
        tf.width = W;
        
        // background
        g = this.graphics;
        g.beginFill(0, .8);
        g.drawRect(0, 0, W, 20);
        g.endFill();
        g = null;
    }
    
}