/**
* 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 );
}
}