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 Loop

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

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;

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

	private var circles:Vector.<Circle>;
	private var pool:Vector.<Circle>;
	
	public function Main( stage:* ) 
	{	
        super();
        stage.addChild( this );
	    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 
{
	
	static public var max_radius:Number = 50;

	/// 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;
	private var shrink: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;
		shrink = false;
		dead = false;
	}
	
	public function outsideSpace():Boolean
	{
		return p.x - r < 0 || p.x + r > SW || p.y - r < 0 || p.y + r > SH;
	}
	
	/// return true if dead
	public function grow( circles:Vector.<Circle> ):Boolean
	{
		// Shrink 
		if ( shrink ) 
		{
			r -= growStep;
			
			if ( r <= 0 ) return true;
			
			return false;
		}
		
		if ( !growing ) return false;
		
		else 	r += growStep;
		
		// if circle is too big, kill it 
		if ( r > max_radius ) 
		{
			growing = false;
			shrink = true;
			f = 0;
			r = max_radius;
		}
		
		
		// stop growing if circle vs edge collision was detected
		if ( outsideSpace() ) 
		{
			growing = false;
			shrink = true;
			f = 0;
			
			if ( p.x - r < 0 ) r = p.x;
			if ( p.y - r < 0 ) r = p.y;
			if ( p.x + r > SW ) r = SW - p.x;
			if ( p.y + r > SH ) r = SH - p.y;
		}
		
		// stop growing if circle vs circle collision was detected 
		for ( var i = 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.shrink = true;
		c.growing = false;
		c.f -- ;
		c.r += d;
		this.f ++;
		this.shrink = false;
		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 && ! shrink;
	}
	
	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 );
	}
}