code on 2008-12-24
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
[SWF(width="465", height="465", backgroundColor="#FFFFFF", frameRate="30")]
public class Water extends Sprite
{
private var canvas:BitmapData;
private var screen:BitmapData;
private var screen2:BitmapData;
private var container:Sprite = new Sprite();
private var roof:Sprite = new Sprite();
private var pool:Pool = new Pool( -100, 465 + 200, 465 - 50, 465 + 50);
private var _blur:BlurFilter = new BlurFilter(32, 32);
private var _rect:Rectangle;
private var _pt:Point = new Point();
private var _drops:Vector.<Drop> = new Vector.<Drop>();
public function Water()
{
var s:Bitmap;
addChild(new Bitmap(canvas = new BitmapData(465, 465, true, 0xFFFFFFFF)));
addChild(s = new Bitmap(screen2 = new BitmapData(465, 465, true, 0x00000000)));
screen = screen2.clone();
s.blendMode = BlendMode.SCREEN;
_rect = canvas.rect;
container.addChild(roof);
container.addChild(pool);
addEventListener("enterFrame", loop);
roof.graphics.beginFill(0);
roof.graphics.drawRect(-100, -50, 465+200, 70);
roof.graphics.endFill();
var b:int = 16;
container.filters = [new BlurFilter(b,b,1)];
}
private function loop(event:Event):void
{
if (Math.random() < 0.08)
{
container.addChild(_drops[_drops.length] = new Drop(pool));
}
var n:uint = _drops.length;
for (var i:uint = 0; i < n; i++)
{
var drop:Drop = _drops[i];
if (drop.update())
{
var s:Number = drop.scaleX;
var matrix:Matrix = new Matrix(s, 0, 0, s, drop.x, drop.y);
//drop.filters = [new BlurFilter(32,32)];
screen.draw(drop, matrix);
container.removeChild(drop);
_drops.splice(i, 1);
i--;
n--;
}
}
pool.update();
canvas.fillRect(_rect, 0x00FFFFFF);
canvas.draw(container);
canvas.threshold(canvas, _rect, _pt, "<", 0x80FFFFFF, 0xFFFFFFFF, 0xFF000000, true);
screen.applyFilter(screen, _rect, _pt, _blur);
screen.draw(screen, null, null, BlendMode.ERASE);
screen2.draw(screen);
screen2.applyFilter(screen2, _rect, _pt, _blur);
}
}
}
import flash.display.Sprite;
class Drop extends Sprite
{
private var _pool:Pool;
private var ay:Number = 0;
private var size:Number = 0;
public var color:uint = 0x000000;
public function Drop(pool:Pool)
{
_pool = pool;
this.x = Math.random() * 465 >> 0;
this.y = 15;
size = Math.random() * 20 + 20;
color = hsl(Math.random()*360, 0.85, 0.6);
graphics.beginFill(color);
graphics.drawCircle(0,0,5);
graphics.endFill();
scaleX = scaleY = Math.random();
}
public function update():Boolean
{
if (width < size)
{
scaleX += scaleX * 0.45;
scaleY = scaleX;
}
else
{
ay += 0.65;
y += ay;
if (y > _pool.top)
{
_pool.hit(x, y + ay);
return true;
}
}
return false;
}
}
class Pool extends Sprite
{
private var points:Vector.<Particle> = new Vector.<Particle>();
public var left:int = 0;
public var right:int = 0;
public var top:int = 0;
public var bottom:int = 0;
public function Pool(left:int, right:int, top:int, bottom:int)
{
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
var w:int = right - left;
var n:uint = 30;
for (var i:uint = 0; i < n; i++)
{
points[i] = new Particle(w / n * (i + 1) + left, top);
}
update();
}
public function hit(x:Number, y:Number):void
{
var w:int = right - left;
var n:uint = points.length;
var i:uint = (x - left) / (w / n) >> 0;
points[i].move(points[i].x, points[i].y + y);
}
public function update():void
{
graphics.clear();
graphics.beginFill(0x000000);
graphics.moveTo(right, top);
graphics.lineTo(right, bottom);
graphics.lineTo(left, bottom);
graphics.lineTo(left, top);
var n:uint = points.length;
var nx:Number = 0;
var ny:Number = 0;
for (var i:uint = 0; i < n; i++)
{
nx = points[i].x;
if (i>1 && i < n-1)
{
ny = (points[i - 1].y + points[i + 1].y) * .5;
}
else
{
ny = points[i].vy;
}
points[i].move(nx, ny);
points[i].update();
}
for (i = 0; i < n; i++)
{
var p:Particle = points[i];
graphics.lineTo(p.x, p.y);
}
graphics.endFill();
}
}
class Particle
{
private var tx : Number = 0;
private var ty : Number = 0;
private var ox : Number = 0;
private var oy : Number = 0;
public var vx : Number = 0;
public var vy : Number = 0;
public var x : Number = 0;
public var y : Number = 0;
public function Particle(x:Number, y:Number)
{
this.tx = this.vx = this.ox = this.x = x;
this.ty = this.vy = this.oy = this.y = y;
}
public function move(tx:Number, ty:Number):void
{
this.tx = (this.tx + tx) * .5;
this.ty = (this.ty + ty) * .5;
}
public function update():void
{
var nx:Number = (x - ox) * 0.85;
ox = x;
x += (tx - x) * 0.45 + nx;
var ny:Number = (y - oy) * 0.85;
oy = y;
y += (ty - y) * 0.45 + ny;
tx += (vx - tx) * 0.45;
ty += (vy - ty) * 0.45;
}
}
function hsl (h:Number, s:Number, l:Number, a:Number = 0.0):uint { var r:Number = 0, g:Number = 0, b:Number = 0, cmin:Number, cmax:Number; if (s < 0) s = 0; if (s > 1) s = 1; if (l < 0) l = 0; if (l > 1) l = 1; h = h % 360; if (h < 0) h = h + 360; if (l <= 0.5) { cmin = l * ( 1 - s ); cmax = 2 * l - cmin; } else { cmax = l * ( 1 - s ) + s; cmin = 2 * l - cmax; }; r = _h2v(h + 120, cmin, cmax) * 0xFF; g = _h2v(h, cmin, cmax) * 0xFF; b = _h2v(h - 120, cmin, cmax) * 0xFF; a *= 0xFF; return a << 24 | r << 16 | g << 8 | b << 0; }
function _h2v (h:Number, min:Number, max:Number):Number { h = h % 360; if (h < 0) h = h + 360; if (h < 60) return min + (max - min) * h / 60; if (h >= 60 && h < 180) return max; if (h >= 180 && h < 240) return min + (max - min) * (240 - h) / 60; return min; }