/**
* Copyright euakast ( http://wonderfl.net/user/euakast )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3Qi0
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.*;
[SWF(backgroundColor="#000000")]
public class Sketch20110215 extends Sprite {
private static const STAGE_WIDTH:int = 465;
private static const STAGE_HEIGHT:int = 465;
private static const NUM_BLOB:int = 20;
private static const ZERO_POINT:Point = new Point();
private var _bitmap:Bitmap;
private var _bitmapData:BitmapData;
private var _blobs:Array;
private var _positions:Array;
private var _targets:Array;
private var _timer:Timer;
private var _color:HSVColor;
public function Sketch20110215():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
var background:Sprite = new Sprite();
background.graphics.beginFill(0x0);
background.graphics.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
background.graphics.endFill();
addChild(background);
_bitmapData = new BitmapData(STAGE_WIDTH, STAGE_HEIGHT, true, 0x0);
_bitmap = new Bitmap(_bitmapData);
addChild(_bitmap);
_blobs = [];
var blob:Blob = new Blob(20, 20);
blob.maxForce = 6;
blob.maxSpeed = 20;
_blobs.push(blob);
_targets = [];
_positions = [];
for (var i:int = 0 ; i < _blobs.length; ++i) {
var b:Blob = _blobs[i];
b.position = new Vec2d(_bitmapData.width * 0.5, _bitmapData.height * 0.5);
var position:Array = [];
for (var j:int = 0; j < NUM_BLOB; ++j) {
var pos:Vec2d = new Vec2d(_bitmapData.width * 0.5, _bitmapData.height * 0.5);
position.push(pos);
}
_positions.push(position);
_targets.push(new Vec2d(Random.random(_bitmapData.width), Random.random(_bitmapData.height)));
}
_color = new HSVColor(360, 255, 255),
_timer = new Timer(400);
_timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void {
var offset:Number = 40;
_targets[0] = new Vec2d(Random.random(offset, _bitmapData.width - offset), Random.random(offset, _bitmapData.height - offset));
});
_timer.start();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(e:Event):void {
_bitmapData.lock();
_bitmapData.fillRect(_bitmapData.rect, 0x0);
var colorTransform:ColorTransform = new ColorTransform();
_color.h += 1;
for (var i:int = 0; i < _blobs.length; ++i) {
var b:Blob = _blobs[i];
var target:Vec2d = _targets[i];
b.seek(new Vec2d(target.x, target.y));
b.update();
var position:Array = _positions[i];
position.pop();
b = _blobs[i];
var pos:Vec2d = new Vec2d(b.x, b.y);
position.unshift(pos);
for (var j:int = 0; j < NUM_BLOB; ++j) {
pos = position[j];
var scale:Number = 1 - (j * 0.02);
var tmp:HSVColor = _color.clone();
tmp.h = (_color.h - j * 2) + NUM_BLOB * 2;
colorTransform.color = tmp.value;
_bitmapData.draw(b, new Matrix(scale, 0, 0, scale, pos.x, pos.y), null, BlendMode.ADD);
_bitmapData.draw(b, new Matrix(scale * 2, 0, 0, scale * 2, pos.x, pos.y), colorTransform, BlendMode.ADD);
}
}
_bitmapData.threshold(_bitmapData, _bitmapData.rect, ZERO_POINT, "<", 0xCCFFFFFF, 0x00000000);
_bitmapData.unlock();
}
}
}
import flash.display.*;
import flash.filters.*;
class Blob extends Sprite {
private var _position:Vec2d;
private var _velocity:Vec2d;
private var _steeringForce:Vec2d;
private var _maxForce:Number;
private var _maxSpeed:Number;
private var _mass:Number;
private var _width:Number;
private var _height:Number;
public function Blob(width:Number = 10.0, height:Number = 10.0) {
_width = width;
_height = height;
_maxForce = 1.0;
_maxSpeed = 10.0;
_mass = 1.0;
_position = new Vec2d();
_velocity = new Vec2d();
_steeringForce = new Vec2d();
blendMode = BlendMode.ADD;
draw();
filters = [new BlurFilter(_width, _height, 2)];
}
private function draw():void {
graphics.beginFill(0xFFFFFF);
graphics.drawEllipse(_width * -0.5, _height * -0.5, _width, _height);
graphics.endFill();
}
public function update():void {
_steeringForce.truncate(_maxForce);
_steeringForce = _steeringForce.scale(1 / _mass);
_velocity = _velocity.add(_steeringForce);
_steeringForce = new Vec2d();
_velocity.truncate(_maxSpeed);
_position = _position.add(_velocity);
x = _position.x;
y = _position.y;
}
public function seek(target:Vec2d):void {
var desiredVelocity:Vec2d = target.sub(_position);
desiredVelocity.normalize();
desiredVelocity = desiredVelocity.scale(_maxSpeed);
var force:Vec2d = desiredVelocity.sub(_velocity);
_steeringForce = _steeringForce.add(force);
}
public function get position():Vec2d { return _position; }
public function set position(value:Vec2d):void { _position = value; }
public function get velocity():Vec2d { return _velocity; }
public function set velocity(value:Vec2d):void { _velocity = value; }
public function get maxForce():Number { return _maxForce; }
public function set maxForce(value:Number):void { _maxForce = value; }
public function get maxSpeed():Number { return _maxSpeed; }
public function set maxSpeed(value:Number):void { _maxSpeed = value; }
}
class Vec2d {
public var x:Number, y:Number;
public function Vec2d(ax:Number = 0.0, ay:Number = 0.0) { x = ax; y = ay; }
public function clone():Vec2d { return new Vec2d(x, y); }
public function set(ax:Number, ay:Number):void { x = ax; y = ay; }
public function get length():Number { return Math.sqrt(x * x + y * y); }
public function set length(value:Number):void { var a:Number = angle; x = Math.cos(a) * value; y = Math.sin(a) * value; }
public function get lengthSqrt():Number { return x * x + y * y; }
public function get angle():Number { return Math.atan2(y, x); }
public function normalize():void { var invS:Number = 1 / length; x *= invS; y *= invS; }
public function normalized():Vec2d { var invS:Number = 1 / length; return new Vec2d(x * invS, y * invS); }
public function add(rhs:Vec2d):Vec2d { return new Vec2d(x + rhs.x, y + rhs.y); }
public function sub(rhs:Vec2d):Vec2d { return new Vec2d(x - rhs.x, y - rhs.y); }
public function mul(rhs:Vec2d):Vec2d { return new Vec2d(x * rhs.x, y * rhs.y); }
public function div(rhs:Vec2d):Vec2d { return new Vec2d(x / rhs.x, y / rhs.y); }
public function dot(rhs:Vec2d):Number { return x * rhs.x + y * rhs.y; }
public function cross(rhs:Vec2d):Number { return x * rhs.y - y * rhs.x; }
public function scale(s:Number):Vec2d { return new Vec2d(x * s, y * s); }
public function distance(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return Math.sqrt(dx * dx + dy * dy); }
public function distanceSqrd(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return dx * dx + dy * dy; }
public function rotate(angle:Number):void { var cosa:Number = Math.cos(angle); var sina:Number = Math.sin(angle); var rx:Number = x * cosa - y * sina; y = x * sina + y * cosa; x = rx; }
public function truncate(max:Number):void { this.length = Math.min(max, this.length); }
}
class Random {
public static function random(min:Number = 0, max:Number = NaN):Number {
if (isNaN(max)) { max = min; min = 0; }
return min + Math.random() * (max - min);
}
}
class HSVColor {
private static const MIN_HUE:Number = 0.0;
private static const MAX_HUE:Number = 360.0;
private static const MIN_SATURATION:Number = 0.0;
private static const MAX_SATURATION:Number = 255.0;
private static const MIN_VALUE:Number = 0.0;
private static const MAX_VALUE:Number = 255.0;
private static const MIN_ALPHA:Number = 0.0;
private static const MAX_ALPHA:Number = 255.0;
private var _h:uint, _s:Number, _v:Number, _a:Number;
public function HSVColor(h:Number = 0.0, s:Number = 0.0, v:Number = 0.0, a:Number = 255.0) {
setHSV(h, s, v);
this.a = a;
}
public function clone():HSVColor { return new HSVColor(h, s, v, a); }
public function setHSV(h:Number, s:Number, v:Number):void { this.h = h; this.s = s; this.v = v; }
public function get h():Number { return _h; }
public function set h(value:Number):void { _h = value % MAX_HUE; }
public function get s():Number { return _s; }
public function set s(value:Number):void { _s = constrain(value, MIN_SATURATION, MAX_SATURATION); }
public function get v():Number { return _v; }
public function set v(value:Number):void { _v = constrain(value, MIN_VALUE, MAX_VALUE); }
public function get a():Number { return _a; }
public function set a(value:Number):void { _a = constrain(value, MIN_ALPHA, MAX_ALPHA); }
public function get value():uint {
var r:uint, g:uint, b:uint;
if (_s == 0) {
r = g = b = _v;
} else {
var st:Number = _s * (1 / 255);
var i:int = Math.floor(_h / 60);
var f:Number = _h / 60 - i;
var p:Number = Math.round(_v * (1 - st));
var q:Number = Math.round(_v * (1 - f * st));
var t:Number = Math.round(_v * (1 - (1 - f) * st));
switch (i) {
case 0: r = _v; g = t; b = q; break;
case 1: r = q; g = _v; b = t; break;
case 2: r = p; g = _v; b = t; break;
case 3: r = p; g = q; b = _v; break;
case 4: r = t; g = p; b = _v; break;
case 5: r = _v; g = p; b = q; break;
}
}
return r << 16 | g << 8 | b;
}
public function set value(value:uint):void { update(value); }
private function update(value:uint):void {
_a = value >> 24;
var r:uint = value >> 16 & 0xFF, g:uint = value >> 8 & 0xFF, b:uint = value & 0xFF;
var max:Number = Math.max(r, g, b);
var min:Number = Math.min(r, g, b);
var n:Number = max - min;
if (n == 0) {
_h = MIN_HUE; _s = MIN_SATURATION; _v = MIN_VALUE;
} else {
_s = n / max; _v = max;
switch (max) {
case r: _h = 60 * (g - b) / n; break;
case g: _h = 60 * (b - r) / n + 120; break;
case b: _h = 60 * (r - g) / n + 240; break;
}
}
}
private function constrain(value:Number, min:Number, max:Number):Number { return (value > max) ? max : (value < min) ? min : value; }
}