Marching Ants Selection
@author Will Costa
@author http://www.williancosta.com/blog
/**
* Copyright will_costa ( http://wonderfl.net/user/will_costa )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dmLS
*/
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
/**
* @author Will Costa
* @author http://www.williancosta.com/blog
*/
[SWF(backgroundColor="#FFFFFF", frameRate="30", width="465", height="465")]
public class Main extends Sprite {
public static const WIDTH : Number = 465;
public static const HEIGHT : Number = 465;
public static const MAX_ANTS : int = 1500;
private var _ants : Vector.<Ant>;
private var _freeAnts : Vector.<Ant>;
private var _firstPoint : Point;
private var _rect : Rectangle;
private var _textField : TextField;
private var _variation : Number = 0;
private var _spacing : Number = 5;
public function Main() {
_textField = new TextField();
_textField.autoSize = "left";
_textField.selectable = false;
_textField.text = "Click and drag to create a rectangle";
addChild(_textField);
_ants = new Vector.<Ant>();
_freeAnts = new Vector.<Ant>();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
}
//----------------------------------
// Private Functions
//----------------------------------
private function drawMarquee() : void {
while(_ants.length) removeChild(_ants.pop());
if(_rect.width < 0) {
_rect.width *= -1;
_rect.x -= _rect.width;
}
if(_rect.height < 0) {
_rect.height *= -1;
_rect.y -= _rect.height;
}
var n : int = _rect.width / _spacing;
var ant : Ant;
for (var i : int = 0;i < n;i++) {
ant = new Ant();
ant.x = _variation + _rect.x + i * _spacing;
ant.y = _rect.y;
addChild(ant);
_ants.push(ant);
ant = new Ant();
ant.x = _spacing - _variation + _rect.x + i * _spacing;
ant.y = _rect.y + _rect.height;
addChild(ant);
_ants.push(ant);
}
n = _rect.height / _spacing;
for (i = 0;i < n;i++) {
ant = new Ant();
ant.x = _rect.x ;
ant.y = _spacing - _variation + _rect.y + i * _spacing;
ant.rotation = 90;
addChild(ant);
_ants.push(ant);
ant = new Ant();
ant.x = _rect.x + _rect.width;
ant.y = _variation + _rect.y + i * _spacing;
ant.rotation = 90;
addChild(ant);
_ants.push(ant);
}
}
//----------------------------------
// Event Handlers
//----------------------------------
private function onEnterFrameHandler(event : Event) : void {
for each (var ant : Ant in _freeAnts) {
ant.run();
if(ant.x < 0 || ant.x > WIDTH || ant.y < 0 || ant.y > HEIGHT) {
removeChild(ant);
_freeAnts.splice(_freeAnts.indexOf(ant), 1);
}
}
_variation += .5;
_variation = _variation % _spacing;
if(_rect) drawMarquee();
}
private function onMouseDownHandler(event : MouseEvent) : void {
_firstPoint = new Point(mouseX, mouseY);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onMouseMoveHandler(event : MouseEvent) : void {
_rect = new Rectangle(_firstPoint.x, _firstPoint.y, mouseX - _firstPoint.x, mouseY - _firstPoint.y);
}
private function onMouseUpHandler(event : MouseEvent) : void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
for each (var ant : Ant in _ants) {
_freeAnts.push(ant);
ant.interval = Math.random() * 30;
if(_freeAnts.length > MAX_ANTS) removeChild(_freeAnts.shift());
}
_ants = new Vector.<Ant>();
_rect = null;
}
}
}
import flash.display.Sprite;
class Ant extends Sprite {
public var interval : Number = 0;
private var _speed : Number = 0;
private var _angle : Number = 0;
public function Ant() {
_speed = Math.random() + 1;
graphics.beginFill(0);
graphics.drawRect(-1, -.5, 3, 1);
}
public function run() : void {
if(interval > 0) {
interval--;
} else {
if(Math.random() < .01) interval = 15 + Math.random() * 10;
move();
}
}
private function move() : void {
_angle += (Math.random() * 60 - 30) * Math.PI / 180;
x += Math.cos(_angle) * _speed;
y += Math.sin(_angle) * _speed;
rotation = _angle * 180 / Math.PI;
}
}