Tentacle 2008-12-31
...
@author DefaultUser (Tools -> Custom Arguments...)
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Sprite;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.Event;
import flash.events.TimerEvent;
[SWF(width="465", height="465", backgroundColor="0xCCCCCC", frameRate="0")]
/**
* ...
* @author DefaultUser (Tools -> Custom Arguments...)
*/
public class Demo extends Sprite
{
private var _timer:Timer;
private var _frameRate:int = 24;
private var _tentacles:Array;
private var _numTentacles:int = 15;
private var _screen:Bitmap;
private var _cx:Number;
private var _cy:Number;
private var rand:Function;
private var _t:int;
public function Demo()
{
rand = Math.random;
_timer = new Timer(1000 / _frameRate);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(e.type, arguments.callee);
init();
}
private function timerHandler(e:TimerEvent):void
{
var t:int = getTimer();
var dt:int = t - _t;
_t = t;
update(dt);
stage.invalidate();
}
private function init():void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_screen = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, false));
addChild(_screen);
_cx = stage.stageWidth * 0.5;
_cy = stage.stageHeight * 0.5;
var t:Tentacle;
_tentacles = new Array();
for (var i:int = 0; i < _numTentacles; i++) {
t = new Tentacle(_cx, _cy, (mouseX - _cx) * 0.0001, (mouseY - _cy) * 0.0001, (3 + 1.5 * rand())*1000);
_tentacles.push(t);
}
_timer.start();
_t = getTimer();
}
private function update(dt:int):void {
_screen.bitmapData.lock();
clearScreen(0xFFFFFF);
_tentacles.forEach(function (t:Tentacle, index:int, ary:Array):void {
t.age(dt);
addForce(t);
t.move(dt);
_screen.bitmapData.draw(t);
});
_screen.bitmapData.unlock();
}
private function addForce( t:Tentacle):void {
var mx:Number = mouseX;
var my:Number = mouseY;
var r:Number = 1 / t.nodes.length;
var n:Node;
t.head.addForce((mx-_cx) * 0.00005 + 0.1 * rand() - 0.05, (my - _cy) * 0.00005 + 0.1 * rand() - 0.05);
for (var i:int = 1; i < t.nodes.length; i++) {
n = t.nodes[i];
n.addForce(i * r * (mx - n.x) * 0.0001, i * r * (my- n.y) * 0.0001);
}
}
private function clearScreen(c:uint = 0x000000):void {
//trace('clear');
_screen.bitmapData.fillRect(_screen.bitmapData.rect, c);
}
}
}
import flash.display.Shape;
class Tentacle extends Shape {
public var nodes:Array;
public var life:int;
public var head:Node;
public var grow:Boolean = true;
public var r:int;
public var g:int;
public var b:int;
public function Tentacle(x:Number = 0, y:Number = 0, vx:Number = 0, vy:Number = 0, life:int = 3500) {
super();
nodes = new Array();
head = new Node(x, y, vx, vy);
this.life = life;
r = 127 + int(127 * Math.random());
g = 127 + int(127 * Math.random());
b = 127 + int(127 * Math.random());
}
public function move(t:int):void {
if (!(nodes.length > 0)) return;
var scale:Number = 1 / nodes.length;
var th:Number;
var n:Node;
var c:uint;
var pow:Number;
graphics.clear();
n = nodes[0];
graphics.moveTo(n.x, n.y);
for (var i:int = 1; i < nodes.length; i++) {
n = nodes[i];
n.move(t);
pow = Math.pow((scale * (nodes.length - i)), 2);
th = pow * 100;
pow = i * scale;
c = (pow * r << 16) | (pow * g << 8) | (pow * b);
graphics.lineStyle(th , c);
graphics.lineTo(n.x, n.y);
}
head.move(t);
//graphics.lineTo(head.x, head.y);
}
public function age(t:Number):void {
var node:Node;
life -= t;
if (life < 0) {
grow = false;
nodes.pop();
if (nodes.length < 2) {
grow = true;
head.x = nodes[0].x;
head.y = nodes[0].y;
head.vx = nodes[0].vx;
head.vy = nodes[0].vy;
life = (3 + 1.5 * Math.random()) * 1000;
}
}else {
node = new Node(head.x , head.y, 0, 0);
nodes.push(node);
}
}
}
class Node {
public var x:Number;
public var y:Number;
public var vx:Number;
public var vy:Number;
private var _friction:Number = 0.95;
public function Node(x:Number = 0, y:Number = 0, vx:Number = 0, vy:Number = 0):void {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
}
public function addForce(ax:Number, ay:Number):void {
vx += ax;
vy += ay;
}
public function move(dt:Number):void {
x += vx * dt;
y += vy * dt;
vx *= _friction;
vy *= _friction;
}
}