/**
* Copyright onedayitwillmake ( http://wonderfl.net/user/onedayitwillmake )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/smwm
*/
/**
* @Revision
* -Hold mouse down to apply attracting force
* @author Mario Gonzalez
* @see http://onedayitwillmake.com/
*/
package
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.display.BitmapData;
import flash.display.PixelSnapping
import flash.display.Bitmap;
import flash.filters.ColorMatrixFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
[SWF(width="465", height="465", background="#000000")]
public class Proximity extends Sprite
{
//Parameters
private var _cCount :int = 0;
private var _cMax :int = 80;
//Rendering
private var _canvas :Sprite;
public var _canvasGraphics :Graphics
//Reference
public var _lastCircle :Circle;
//Movement
public var _mousePressed :Boolean = false;
public function Proximity()
{
stage.quality = StageQuality.LOW
addChildAt(createBG(), 0);
addChild(_canvas = new Sprite());
_canvasGraphics = _canvas.graphics;
create();
addEventListener(Event.ENTER_FRAME, loop);
stage.addEventListener(MouseEvent.MOUSE_DOWN, toggleMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, toggleMouseDown);
}
private function createBG():Sprite
{
trace(Wonderfl)
var matr:Matrix = new Matrix();
matr.createGradientBox(465, 465, Math.PI / 2, 0, 0);
var bg:Sprite = new Sprite();
bg.graphics.beginGradientFill
(
GradientType.LINEAR,
[0x000021, 0x000000], //colors
[1, 1], //alphas
[0, 255], //ratios
matr, //matrix
SpreadMethod.PAD
);
bg.graphics.drawRect(0, 0, 465, 465);
bg.graphics.endFill();
return bg;
}
/**
* Main program loop
*/
private function loop(e:Event):void
{
draw();
}
/**
* Creates more circles if we have not reached the maximum count
*/
public function create():void
{
if(_cCount >= _cMax) return;
var c:Circle;
for(var i:int = 0; i < _cMax; i++)
{
c =new Circle(this);
c.x = c._ix = Math.random() * (stage.stageWidth - 26) + 13;
c.y = c._iy = Math.random() * (stage.stageHeight - 26) + 13;
_canvas.addChild(c);
_cCount++;
if(_lastCircle)
c._prev = _lastCircle;
_lastCircle = c;
}
}
/**
* Draws the proximity field between the circles
*/
public function draw():void
{
_canvas.graphics.clear();
_canvas.graphics.lineStyle(0.5, 0xfffffff, 0.3);
if(_lastCircle == null) return;
_lastCircle.checkForProximity(_lastCircle._prev);
_lastCircle.move();
}
public function toggleMouseDown(e:MouseEvent):void
{
if(_mousePressed)
_mousePressed = false;
else
_mousePressed = true;
}
}
}
import flash.display.Shape;
import flash.display.BlendMode
import flash.display.Sprite;
/**
* Circles that live in the feild
*/
class Circle extends Sprite
{
private var _radius :Number = Math.random() * 5 + 5;
private var _curveModifier :Number = Math.random() * 50 - 25;
public var _p :Proximity; //reference
public var _prev :Circle; //Linked list style behavior
//MOVEMENT
public static var ACC_PARAM:Number = 0.1;
public static var VELOCITY_PARAM:Number = 0.8
public var _ix:Number;
public var _iy:Number;
public var _vx:Number = 0.1;
public var _vy:Number = 0;
public var _ax:Number = 0;
public var _ay:Number = 0;
/**
* Individual Circles know only the Circle created previously to their own
*/
public function Circle(p:Proximity):void
{
_p = p;
blendMode = BlendMode.ADD
graphics.beginFill(Math.random() * 255 * 255 * 255, 0.5)
graphics.drawCircle(0, 0, _radius);
graphics.endFill();
/*
graphics.beginFill(Math.random() * 255 | 255 << 255)
graphics.drawCircle(0, 0, 4);
graphics.endFill();
*/
}
/**
* Check all previous circles for proximity, and do [something]
* There is no need for each circle to check the ones ahead,
* because they've already checked against this one.
*
* Called recursively for this circle, until the linked list reaches the first circle.
* Once it does, it calls checkForProximity on its '_prev'
* The sequence repeats until there are no more previous ones
*
* @param tc:Circle The 'test circle' we will check against.
*/
public function checkForProximity(tc:Circle):void
{
if(tc == null) return; // This is the first circle created (unless error of course!)
var d:Number = Math.sqrt((x - tc.x) * (x - tc.x) + (y - tc.y) * (y - tc.y));
if(d < 90)
{
_p._canvasGraphics.moveTo(x, y);
//_p._canvasGraphics.lineTo(tc.x, tc.y);
//_p._canvasGraphics.curveTo(tc.x, tc.y);
_p._canvasGraphics.curveTo((x + tc.x) * 0.5, (y + tc.y) * 0.5 + _curveModifier, tc.x, tc.y);
}
//Keep checking backwards for proximity, until you reach the first circle
if(tc._prev)
checkForProximity(tc._prev);
else if(_prev) //Reached first circle. We are the last created circle, so continue the loop until we reach the first
_prev.checkForProximity(_prev._prev);
}
/**
* Moves the circle, initial position relative to mouse attraction/repelling force
*/
public function move():void
{
//Don't let the force become too strong, by saying the distance will always be X at min
var dist:Number = Math.max(Math.sqrt((x - stage.mouseX) * (x - stage.mouseX) + (y - stage.mouseY) * (y - stage.mouseY)), 40);
var dy:Number = stage.mouseY - y;
var dx:Number = stage.mouseX - x
var angle:Number = Math.atan2(dy, dx);
var f:Number = 1 / dist * 400 * ((_p._mousePressed == true) ? 1 : -1);
_ax += Math.cos(angle) * f;
_ay += Math.sin(angle) * f;
_ax += (_ix - x) * ACC_PARAM;
_ay += (_iy - y) * ACC_PARAM;
_vx = (_vx + _ax) * VELOCITY_PARAM;
_vy = (_vy + _ay) * VELOCITY_PARAM;
x += _vx;
y += _vy;
_ax = _ay = 0;
if(_prev) //Call move on all circles
_prev.move();
}
public function destroy():void
{
// _p._firstCircle = this;
}
}