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

Circle Packing POP

Get Adobe Flash player
by makc3d 23 Jan 2017
/**
 * Copyright makc3d ( http://wonderfl.net/user/makc3d )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6OGi
 */

// forked from WLAD's Circle Packing Loop
package {
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            // write as3 code here..
            graphics.beginFill(0);
            graphics.drawRect(0,0,465,465);
            new Main( stage );
        }
    }
}

var SW:int = 0;
var SH:int = 0;
var FPS:int = 0;

import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.*;

/**
 * ...
 * @author www.wad1m.com, twitter:@_wad1m
 */
class Main extends Sprite 
{

	private var circles:Vector.<Circle>;
	private var pool:Vector.<Circle>;

        public static var tf:TextField;
	
	public function Main( stage:* ) 
	{	
        super();
        stage.addChild( this );
        
            tf = new TextField;
            tf.textColor = 0xffffff;
            tf.text = '0';
            addChild(tf);

	    FPS = int( stage.frameRate = 60 );
		SW = stage.stageWidth;
		SH = stage.stageHeight;
		
		circles = new Vector.<Circle>();
		pool = new Vector.<Circle>();
		
		makeCircle();
		
		addEventListener('enterFrame', update );
	}
	
	private function makeCircle():Circle
	{
		var p:Point = new Point( Math.random() * SW, Math.random() * SH );
		
		var nc:Circle;
		
		if ( pool.length > 0 ) nc = pool.pop();
		else nc = new Circle();
		
		nc.reset();
		nc.p = p;
		nc.r = 5;
		nc.growStep = 0.22;
		
		for each( var c:Circle in circles ) if ( c.collides( nc ) ) return null;
		
		circles.push( nc );
		
		return nc;
	}
	
	private var frameCount:int = 0;
	private var frameTrigger:int = 4;
	private var spawnCount:int = 20;
	
	private function update(_:*):void
	{
		graphics.clear();
		
		if ( ++frameCount > frameTrigger ) 
		{
			frameCount = 0;
			
			for( var s:int = 0; s < spawnCount; ++s ) makeCircle();
		}
		
		for each( var c:Circle in circles )
		{
			if ( c.grow( circles ) ) 
			{
				pool.push( c );
				continue;
			}
			
			//graphics.lineStyle( 2, Std.int( 0x40 + 0xBF * c.r / Circle.max_radius ) << 8 );	
			//graphics.lineStyle( 3, Std.int( 0xFF0000 * Math.random() ) );	
			graphics.lineStyle( 2, 0xFFFFFF );	
			graphics.drawCircle( c.p.x , c.p.y, c.r );
		}
		
		for each( c in pool ) 
		{
			var circleIndex:int = circles.indexOf( c );
			if ( circleIndex > -1 ) circles.splice( circleIndex, 1 );
		}
	}

}
/**
 * ...
 * @author www.wad1m.com, twitter:@_wad1m
 */
class Circle 
{
	/// fitness 
	public var f:int;
	/// radius
	public var r:Number;
	/// position
	public var p:Point;
	public var dead:Boolean = false;
	
	public var growStep:Number = 1;
	private var growing:Boolean;
	
	public function Circle( p:Point = null, r:Number = 0 ) 
	{
		if ( r == 0 ) this.r = Math.random() * 20 + 10;
		else this.r = Math.abs( r );
		this.p = p == null ? new Point() : p;
		reset();
	}
	
	public function reset():void
	{
		f = 0; 
		growing = true;
		dead = false;
	}
	
	/// return true if dead
	public function grow( circles:Vector.<Circle> ):Boolean
	{		
		if ( !growing ) return true;
		
		else 	r += growStep;

                // just how large can it get ?
                Main.tf.text = Math.max(r, parseFloat(Main.tf.text)).toFixed(1);
		
		// stop growing if circle vs circle collision was detected 
		for ( var i:int = 0; i < circles.length; ++i )
		{
			if ( circles[ i ] == this ) continue;
			
			var d:Number = distance( circles[ i ] );
			
			if ( d <= 0 ) 
			{	
				if ( circles[ i ].f == f )  {
					if ( Math.random() > 0.5 ) circles[ i ].eat( this, d );
					else this.eat( circles[ i ], d );
				} 	else if( circles[ i ].f > f ) 
					circles[ i ].eat( this, d );
				else this.eat( circles[ i ], d );
				
				//break;
			}
		}	
		return false;
	}
	
	/// d - distance
	public function eat( c:Circle, d:Number ):void
	{
		c.growing = false;
		c.f -- ;
		c.r += d;
                // if edges do not pop circles, this causes them grow forever. so...
		//this.f ++;
		this.growing = true;
		shake();
	}
	
	public function shake():void
	{		
		return;
		p = p.add( new Point( 
			( Math.random() * 2 * growStep - growStep ),
			( Math.random() * 2 * growStep - growStep ) ) );				
	}
	
	public function isFrozen():Boolean 
	{
		return ! growing;
	}
	
	public function distance( c:Circle ):Number
	{
		return Point.distance( c.p, p ) - ( r + c.r );
	}
	
	public function collides( c:Circle ):Boolean
	{
		return Point.distance( c.p, p ) <= r + c.r;
	}
	
	public function draw( g:Graphics ):void
	{
		g.drawCircle( p.x, p.y, r );
	}
}