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

bubble sort (4teach)

bubble sorting visualization (4teaching).
inspired on http://wonderfl.net/c/8rbD
thanks to Ms. Fabiana C. Guedes.
Universidade Federal de Itajubá - Campus Itabira
git https://github.com/thyfl/eco-010/tree/6649fa0593d1e2e31f37e8440123a048146d8fba/fabiana/extras/bubble
@author thi
Get Adobe Flash player
by Thy 21 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/pXmW
 */

package 
{
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    
    /**
     * bubble sorting visualization (4teaching).
     * inspired on http://wonderfl.net/c/8rbD
     * thanks to Ms. Fabiana C. Guedes.
     * Universidade Federal de Itajubá - Campus Itabira
     * git https://github.com/thyfl/eco-010/tree/6649fa0593d1e2e31f37e8440123a048146d8fba/fabiana/extras/bubble
     * @author thi
     */
    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(bubbles.bubbles); // bubbles
                this.addChild(text); // input
                this.addChild(text2); // result
            
            // 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
        }
        
        // 
        private var bubbles:Bubbles = new Bubbles(), // bubble's list's list
                    //
                    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 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;
            
            // bubbles
                var b:Bubbles = bubbles;
                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
            b.zoom(W, H); // adjust the bubbles zooming
        }
        
    }
    
}


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
        
        actual = last = null;
    } // init
    
    private var actual:Bubble, last:Bubble;
    public function sort():String
    {
        var b:Bubble = bubbles,
            //b2:Bubble, // hold last bubble
            next:Bubble,
            s:String = "";
        
        //
        if (actual === null || actual === last )
            actual = bubbles.next;
        
        b = bubbles;
        while ((b = b.next) !== null)
        {
            // finish when we got to the last bubble
            if ((next = b.next) === null)
            {
                _upper = b; // b is the last/up bubble; _upper is used on zooming
                break;
            }
            
            s += String(b.info); // sorted string
        }
        
        b = actual;
        // bubble that will pass
        if((next = b.next) !== null && bubbles.next !== last)
        {
            // comparing color
            
            if (next.next !== last)
            {
                b.comparing();
                next.comparing();
            }
            if (b.prev)
                b.prev.normal();
            
            // you shall not pass
            if (next.info >= b.info)
            {
                b.passing = false;
                b.teta *= .2;
                
                // bubble stops
                if (next === last)
                {
                    last = b;
                    next.stop();
                    b.stop();
                } else
                    actual = actual.next;
            } else
            
            // 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)
                {
                    // bubble stops
                    if (next.next === last)
                    {
                        last = b;
                        b.stop();
                        b.passing = false;
                    }
                    
                    //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;
                    
                }
            }
        } // 1 bubble
        else
        // bubble stops
        {
            last = b;
            b.stop();
            b.passing = false;
        }
        
        b = _upper;
        // 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 / bubbles.scaleY;
        var min:Number = Math.min(W / bubbles.width, (H - _y) / _h);
        bubbles.scaleX = bubbles.scaleY += (min - bubbles.scaleY) * .2;
        return bubbles.scaleY;
    }
    
}


import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.filters.GlowFilter;
/**
 * blub.
 * TODO: make it pretty.
 * TODO: generalize
 * @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() 
    {
        
    }
    
    // vector without bmData's cpyPixel
    public function draw(info:Number, rm:Number, ro:Number):Bubble
    {
        // information
        this.passing = false;
        this.info = info;
        radius = rm * info * ro;
        
        // draw it
        var g:Graphics = this.graphics;
        g.clear();
        //g.lineStyle(.5 , 0xFFFFFF, .1);
        g.beginFill(0x707090, .4);
        g.drawCircle(0, 0, radius);
        g.endFill();
        g = null;
        
        return this;
    }
    
    public function clear():Bubble
    {
        this.graphics.clear();
        return this;
    }
    
    public function stop():void
    {
        // draw it
        var g:Graphics = this.graphics;
        g.clear();
        g.beginFill(0x709080, .4);
        g.drawCircle(0, 0, radius);
        g.endFill();
        g = null;
        
    }
    
    public function comparing():void
    {
        // draw it
        var g:Graphics = this.graphics;
        g.clear();
        g.beginFill(0x303030, .4);
        g.drawCircle(0, 0, radius);
        g.endFill();
        g = null;
    }
    
    public function normal():void
    {
        // draw it
        var g:Graphics = this.graphics;
        g.clear();
        g.beginFill(0x707090, .4);
        g.drawCircle(0, 0, radius);
        g.endFill();
        g = null;
    }
    
}

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;
    }
    
}