Tornado
/**
* Copyright bruno.imbrizi ( http://wonderfl.net/user/bruno.imbrizi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gT2K
*/
// @author Bruno Imbrizi http://brunoimbrizi.com
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
public class Tornado extends Sprite
{
private var _anchors :Vector.<Point> = new Vector.<Point>();
private var _bmp :Bitmap;
private var _bmpData :BitmapData;
private var _spriteP :Sprite;
private var _spriteA :Sprite;
private var _start :Particle;
private var _particle :Particle;
private var _fl :int = 1000;
private var _ct :ColorTransform = new ColorTransform(1, 1, 1, 1, 5, 5, 5);
private var _down :Boolean;
public static const TORNADO_HEIGHT :int = 465;
[SWF(width="465", height="465", frameRate="30")]
public function Tornado()
{
initSprite();
initBitmap();
initAnchors();
initListeners();
}
private function initSprite():void
{
_spriteP = new Sprite();
addChild(_spriteP);
_spriteA = new Sprite();
}
private function initBitmap():void
{
_bmpData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFFFF);
_bmp = new Bitmap(_bmpData);
addChild(_bmp);
addChild(_spriteA);
}
private function initAnchors():void
{
var a:Point;
for (var i:int = 0; i < 4; i++)
{
a = new Point(int(stage.stageWidth * .5 + Math.random() * 100 - 50), int(stage.stageHeight / 3 * i));
_anchors.push(a);
}
}
private function createParticle():void
{
var p:Particle;
var py:Number;
p = new Particle();
p.x = stage.stageWidth * .5 - mouseX;
p.y = mouseY;
py = TORNADO_HEIGHT - p.y;
p.r = (Math.sqrt(1 - (py /= TORNADO_HEIGHT) * py) - 1) * -300;
p.r += Math.random() * 20;
p.angle = Math.PI * .5;
p.life = Math.random() * 2000;
if (!_start) _start = p;
else
{
p.next = _start.next;
_start.next = p;
}
}
private function initListeners():void
{
addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true);
}
private function onEnterFrame(e:Event):void
{
if (_down) createParticle();
var cx:int = stage.stageWidth * .5;
var cy:int = stage.stageHeight * .5;
var cz:int = 0;
var dx:Number;
var dz:Number;
var d:Number;
var r:Number;
var px:Number;
var py:Number;
var scale:Number;
var p:Particle;
var a:Point;
var a0:Point;
var a1:Point;
var aLength:int = _anchors.length;
var i:int;
_bmpData.lock();
_spriteP.graphics.clear();
_spriteP.graphics.lineStyle(0, 0x666666);
_particle = _start;
while (_particle)
{
p = _particle;
if (_particle.next && _particle.next.age > _particle.next.life)
{
_particle.next = _particle.next.next;
}
d = Math.sqrt(p.x * p.x + p.z * p.z);
if (d < p.r) d = p.r;
else d -= 2;
p.x = Math.sin(p.angle) * d;
p.z = Math.cos(p.angle) * d;
i = 0;
for each (a in _anchors)
{
if (p.y < a.y) break;
i++;
}
a0 = (i) ? _anchors[i - 1] : _anchors[i];
if (i < aLength) a1 = _anchors[i]
else
{
_particle = _particle.next;
continue;
}
cx = a0.x + (a1.x - a0.x) * ((p.y - a0.y) / (a1.y - a0.y));
scale = _fl / (_fl + p.z);
px = p.x * scale + cx;
py = p.y * scale;
//p.angle += 5 / d;
p.angle += .1;
p.age++;
if (p.ox)
{
_spriteP.graphics.moveTo(px, py);
_spriteP.graphics.lineTo(p.ox, p.oy);
}
p.ox = px;
p.oy = py;
_particle = _particle.next;
}
_bmpData.applyFilter(_bmpData, _bmpData.rect, new Point(), new BlurFilter(5, 0));
_bmpData.colorTransform(_bmpData.rect, _ct);
_bmpData.draw(_spriteP);
_bmpData.unlock();
// draw anchors
/*
_spriteA.graphics.lineStyle(0, 0);
i = 0;
for each (a in _anchors)
{
if (!i) _spriteA.graphics.moveTo(a.x, a.y);
else _spriteA.graphics.lineTo(a.x, a.y);
i++;
}
*/
}
private function onMouseDown(e:MouseEvent):void
{
_down = true;
}
private function onMouseUp(e:MouseEvent):void
{
_down = false;
}
}
}
class Particle
{
public var x:Number = 0;
public var y:Number = 0;
public var z:Number = 0;
public var ox:Number;
public var oy:Number;
public var age:int = 0;
public var life:int;
public var angle:Number;
public var r:Number;
public var next:Particle;
public function Particle()
{
}
}