2D Particle Waves
Mousedown: create particles (500/frame)
Space to suck up all particles
Wall switch off: no walls, particles removed if outside
Wall switch on: walls, particles are not removed (hold space to clean up particles)
G switch off: no gravity
G switch on: gravity
Wall bounce mode: manages about 120,000 particles
Regular, remove when outside stage: more than 100,000 particles
Regular, no remove when outside stage: more than 100,000 particles
/**
* Copyright antalg ( http://wonderfl.net/user/antalg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iTdf
*/
package {
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Sprite;
import net.hires.debug.Stats;
//
// Mousedown: create particles (500/frame)
// Space to suck up all particles
// Wall bounce mode: manages about 120,000 particles
// Regular, remove when outside stage: more than 100,000 particles
// Regular, no remove when outside stage: more than 100,000 particles
//
[SWF(backgroundColor=0x000000, frameRate=30, width=400, height=400)]
public class FlashTest extends Sprite {
public function FlashTest() {
_bm = new Bitmap(_bmd);
addChild(_bm);
addChild(_txt);
_txt.x = 100;
_txt.width = 300;
_txt.height = 20;
_txt.textColor = _particleColor;
stage.addEventListener(Event.ENTER_FRAME, move);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpOrRelease);
stage.addEventListener(MouseEvent.MOUSE_OUT, mouseUpOrRelease);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
//addChild(new Stats());
// Add switch 1
_switchWalls = false;
addChild(_switch);
_switch.x = 4;
_switch.y = 4;
drawSwitch(_switchWalls);
_switch.addEventListener(MouseEvent.MOUSE_DOWN, switchClick);
// Add switch 2
_switch2Mark = false;
addChild(_switch2);
_switch2.x = 28;
_switch2.y = 4;
drawSwitch2(_switch2Mark);
_switch2.addEventListener(MouseEvent.MOUSE_DOWN, switch2Click);
}
private var _switch:Sprite = new Sprite();
private var _switchWalls:Boolean;
private var _switch2:Sprite = new Sprite();
private var _switch2Mark:Boolean;
private var _frameRate:int = 30;
private var _gravity:Number = 9.8/_frameRate;
private var _txt:TextField = new TextField();
private var _spaceDown:Boolean = false;
private var _mouseDown:Boolean = false;
private var _size:int = 400;
private var _center:int = _size/2;
private var _launchPoint:Point = new Point(_center, _center);
private var _particleColor:uint = 0xFFFFFF;
private var _bgColor:uint = 0x000000;
private const BASEALPHA:int = 26;
private var _bmd:BitmapData = new BitmapData(_size, _size, false, _bgColor);
private var _bm:Bitmap = new Bitmap(_bmd);
private var _particleArray:Vector.<Particle> = new Vector.<Particle>();
private function drawSwitch(frame:Boolean):void {
_switch.graphics.clear();
if(frame) {
_switch.graphics.lineStyle(1,0xFFFFFF);
}
_switch.graphics.beginFill(0xFFFFFF, 0.4);
_switch.graphics.drawRect(0,0,20,20);
_switch.graphics.endFill();
}
private function drawSwitch2(active:Boolean):void {
_switch2.graphics.clear();
_switch2.graphics.beginFill(0xFFFFFF, 0.4);
_switch2.graphics.drawRect(0,0,20,20);
_switch2.graphics.endFill();
_switch2.graphics.lineStyle(2, active?0xFFFFFF:0x000000);
_switch2.graphics.moveTo(16,4);
_switch2.graphics.lineTo(4,4);
_switch2.graphics.lineTo(4,16);
_switch2.graphics.lineTo(16,16);
_switch2.graphics.lineTo(16,11);
_switch2.graphics.lineTo(12,11);
}
private function switchClick(e:MouseEvent):void {
_mouseDown = false;
_switchWalls = !_switchWalls;
drawSwitch(_switchWalls);
}
private function switch2Click(e:MouseEvent):void {
_mouseDown = false;
_switch2Mark = !_switch2Mark;
drawSwitch2(_switch2Mark);
}
private function newParticles(p:Point, number:int = 1):void {
var baseV:Number = 4;
for(;number>0;number--) {
var angle:Number = Math.random()*Math.PI*2;
var v:Point = new Point(Math.cos(angle), Math.sin(angle));
v.normalize(baseV);
_particleArray.push(new Particle(p.x, p.y, v.x, v.y));
}
}
private function mouseMove(e:MouseEvent):void {
_launchPoint.x = stage.mouseX;
_launchPoint.y = stage.mouseY;
}
private function mouseDown(e:MouseEvent):void {
_mouseDown = true;
}
private function mouseUpOrRelease(e:MouseEvent):void {
_mouseDown = false;
}
private function keyDown(e:KeyboardEvent):void {
_spaceDown = true;
}
private function keyUp(e:KeyboardEvent):void {
_spaceDown = false;
}
private function move(e:Event):void {
var newState:BitmapData = new BitmapData(_size, _size, true, _bgColor);
for(var i:int = 0; i<_particleArray.length; ++i) {
var p:Particle = _particleArray[i];
p.x += p.vx;
p.y += p.vy; // Gravity
p.vy += _switch2Mark?_gravity:0;
if(_switchWalls) { // Bounce on walls and cleaner activated
if(p.y>_size || p.y<0) {
p.vy*=-1;
}
if(p.x>_size || p.x<0) {
p.vx*=-1;
}
} else {
if(p.x>_size || p.y>_size || p.x<0 || p.y<0) { // Remove if outside stage
_particleArray[i] = _particleArray[_particleArray.length-1];
i--;
_particleArray.length--;
continue;
}
}
if(_spaceDown) { // If space: suck up particles
var dx:Number = p.x-stage.mouseX;
var dy:Number = p.y-stage.mouseY;
var radSq:int = dx*dx + dy*dy;
p.vx = 0;
p.vy = 0;
p.vx-=dx/2;
p.vy-=dy/2;
if( radSq < 4 ) {
_particleArray[i] = _particleArray[_particleArray.length-1];
i--;
_particleArray.length--;
}
}
var a:int = newState.getPixel32(p.x, p.y)>>24;
newState.setPixel32(p.x, p.y, ((a+BASEALPHA)<<24)|(255<<16)|(255<<8)|255);
}
_bmd.lock();
_bmd.fillRect(_bmd.rect, 0);
_bmd.copyPixels(newState, _bmd.rect, new Point(0,0));
_bmd.unlock();
if(_particleArray.length == 0) {
_particleArray = new Vector.<Particle>();
}
_txt.text = "Particles: "+_particleArray.length;
if(_mouseDown) {
newParticles(_launchPoint, 1000);
}
}
}
}
internal class Particle {
public function Particle(X:Number, Y:Number, VX:Number, VY:Number) {
x = X;
y = Y;
vx = VX;
vy = VY;
}
public var x:Number;
public var y:Number;
public var vx:Number;
public var vy:Number;
}