Snakes
@author Will Costa
* @author http://www.williancosta.com/blog
*
* Inpired on Golan Levin's yellowtail
*
* Click and drag to create new lines
* Catmull-Rom reference http://l00oo.oo00l.com/blog/archives/264
/**
* 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/4cgN
*/
/**
* @author Will Costa
* @author http://www.williancosta.com/blog
*
* Inpired on Golan Levin's yellowtail
*
* Click and drag to create new lines
* Catmull-Rom reference http://l00oo.oo00l.com/blog/archives/264
*/
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
[SWF(backgroundColor="0x000000",frameRate="30")]
public class Main extends Sprite {
public static const WIDTH : Number = 468;
public static const HEIGHT : Number = 468;
private var _currentLine : Line;
private var _lines : Vector.<Line> = new Vector.<Line>();
public function Main() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
//----------------------------------
// Event Handlers
//----------------------------------
private function onEnterFrameHandler(event : Event) : void {
var bounds : Rectangle;
graphics.clear();
graphics.lineStyle(1, 0xFF0000);
for each (var line : Line in _lines) {
line.update();
bounds = line.getBounds(this);
if(line.moving && (bounds.x > WIDTH || bounds.x < -bounds.width || bounds.y > HEIGHT || bounds.y < -bounds.height)) {
_lines.splice(_lines.indexOf(line), 1);
line.dispose();
}
}
}
private function onMouseDownHandler(event : MouseEvent) : void {
_currentLine = new Line();
_currentLine.x = mouseX;
_currentLine.y = mouseY;
addChild(_currentLine);
_lines[_lines.length] = _currentLine;
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onMouseUpHandler(event : MouseEvent) : void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
_currentLine.finishDrawing();
}
private function onMouseMoveHandler(event : MouseEvent) : void {
_currentLine.addPoint(_currentLine.mouseX, _currentLine.mouseY);
}
}
}
import flash.display.Sprite;
internal class Line extends Sprite {
private var _vertices : Vector.<Vertex>;
private var _lastPoint : Vertex;
private var _lastAddedPoint : Vertex;
public var moving : Boolean;
public function Line() {
_vertices = new Vector.<Vertex>();
var point : Vertex = new Vertex(0, 0);
_vertices.push(point);
_lastAddedPoint = point;
}
//----------------------------------
// Public Functions
//----------------------------------
public function addPoint(x : Number, y : Number) : void {
var vertex : Vertex = new Vertex(x, y);
if(_lastAddedPoint && distanceBetweenVertices(vertex, _lastAddedPoint) > 5) {
_vertices.push(vertex);
_lastAddedPoint = vertex;
}
}
public function update() : void {
if(moving) move();
render();
}
public function finishDrawing() : void {
moving = true;
_lastPoint = _vertices[_vertices.length - 1];
}
public function catmullRom(p0 : Number,p1 : Number,p2 : Number,p3 : Number,t : Number) : Number {
var v0 : Number = (p2 - p0) * 0.5;
var v1 : Number = (p3 - p1) * 0.5;
return (2 * p1 - 2 * p2 + v0 + v1) * t * t * t +
(-3 * p1 + 3 * p2 - 2 * v0 - v1) * t * t + v0 * t + p1;
}
public function dispose() : void {
graphics.clear();
parent.removeChild(this);
}
//----------------------------------
// Private Functions
//----------------------------------
private function move() : void {
var a : Vertex = _vertices.shift();
var _x : Number = (a.x + _lastPoint.x);
var _y : Number = (a.y + _lastPoint.y);
addPoint(_x, _y);
}
private function render() : void {
var n : int = _vertices.length;
graphics.clear();
var p0 : Vertex;
var p1 : Vertex;
var p2 : Vertex;
var p3 : Vertex;
var first : Boolean = true;
for (var i : int = 1;i < n - 2;i++) {
p0 = _vertices[i - 1];
p1 = _vertices[i];
p2 = _vertices[i + 1];
p3 = _vertices[i + 2];
for(var ii : Number = 0;ii < 1;ii += .2) {
var x : Number = catmullRom(p0.x, p1.x, p2.x, p3.x, ii);
var y : Number = catmullRom(p0.y, p1.y, p2.y, p3.y, ii);
if(first) {
graphics.moveTo(x, y);
} else {
graphics.lineStyle(2 + i / n * 10, 0xFFFFFF);
graphics.lineTo(x, y);
}
first = false;
}
}
}
private function distanceBetweenVertices(a : Vertex, b : Vertex) : Number {
var dx : Number = b.x - a.x;
var dy : Number = b.y - a.y;
var dist : Number = Math.sqrt(dx * dx + dy * dy);
return dist;
}
}
internal class Vertex {
public var x : Number;
public var y : Number;
public function Vertex(x : Number,y : Number) {
this.x = x;
this.y = y;
};
}