my own bubble simulator
// forked from wh0's particle bullet linked
// forked from wh0's particle bullet
package {
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.events.Event;
public class Bubbles extends Sprite {
private const head:Particle = new Particle();
public function Bubbles() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
Particle.init(stage);
addEventListener(Event.ENTER_FRAME, step);
}
private function step(e:Event):void {
graphics.clear();
var prev:Particle = head;
for (var p:Particle = head.next; p; p = p.next) {
if (p.draw(graphics))
prev.next = p.next;
else
prev = prev.next;
}
head.next = new Particle(Math.random() * stage.stageWidth, stage.stageHeight + 32, head.next);
}
}
}
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Stage;
import flash.utils.getTimer;
class Particle {
internal static var ken:BitmapData;
public static function init(stage:Stage):void {
ken = new BitmapData(stage.stageWidth / 8, stage.stageHeight / 8, false, 0x000000);
ken.perlinNoise(8, 8, 2, getTimer(), false, true);
}
private var px:Number, py:Number, pz:Number, vx:Number;
internal var next:Particle;
public function Particle(x:int = 0, y:int = 0, n:Particle = null) {
px = x;
py = y;
pz = Math.random() * 3 + 1;
vx = Math.random() - 0.5;
next = n;
}
public function draw(g:Graphics):Boolean {
g.lineStyle(0, 0x000000, 1 / pz);
g.drawCircle(px, py, 16 / pz / (1 + py / 800));
if (px >= 0 && px < ken.width * 8 && py >= 0 && py < ken.height * 8) {
var k:uint = ken.getPixel(px / 8, py / 8);
if (pz < 2)
vx += ((k & 0xff) - 128) / 1024.;
else if (pz < 4)
vx += ((k >> 8 & 0xff) - 128) / 1024.;
else
vx += ((k >> 16) - 128) / 1024.;
}
vx *= 0.95;
px += vx / pz;
py -= 4 / pz;
return py < -32;
}
}