forked from: [Stardust] Brilliant Fireworks - forked from: Creek challenge
Stardust Particle Engine
*
* Homepage
* http://code.google.com/p/stardust-particle-engine/
*
* Documentation
* http://stardust-particle-engine.googlecode.com/svn/trunk/docs/index.html
*
* PDF Manual
* http://stardust-particle-engine.googlecode.com/svn/trunk/manual/Stardust%20Particle%20Engine%20Manual.pdf
/**
* Copyright 78ben ( http://wonderfl.net/user/78ben )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qHPs
*/
// forked from cjcat2266's [Stardust] Brilliant Fireworks - forked from: Creek challenge
/**
* Stardust Particle Engine
*
* Homepage
* http://code.google.com/p/stardust-particle-engine/
*
* Documentation
* http://stardust-particle-engine.googlecode.com/svn/trunk/docs/index.html
*
* PDF Manual
* http://stardust-particle-engine.googlecode.com/svn/trunk/manual/Stardust%20Particle%20Engine%20Manual.pdf
*/
package {
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.utils.Timer;
import idv.cjcat.stardust.common.clocks.ImpulseClock;
[SWF(backgroundColor=0x000000, frameRate=60)]
public class Main extends Sprite {
private var timer:Timer = new Timer(1500);
private var clock:ImpulseClock = new ImpulseClock(1);
private var emitter:FireworksEmitter;
private var renderer:LineRenderer;
private var canvas:BitmapData = new BitmapData(465, 465, true, 0);
private var fader:BitmapData = new BitmapData(465, 465, false, 0);
private var glow:BitmapData = new BitmapData(233, 233, false, 0);
public function Main() {
//timer
timer.addEventListener(TimerEvent.TIMER, tick);
timer.start();
//canvas
addChild(new Bitmap(fader));
addChild(new Bitmap(canvas));
var glowBMP:Bitmap = new Bitmap(glow);
glowBMP.blendMode = BlendMode.ADD;
glowBMP.scaleX = glowBMP.scaleY = 2;
addChild(glowBMP);
//Stardust engine
emitter = new FireworksEmitter(clock);
renderer = new LineRenderer(canvas);
renderer.addEmitter(emitter);
//listener
addEventListener(Event.ENTER_FRAME, mainLoop);
tick();
//speed buttons
var btn0:PushButton = new PushButton(this, 10, 10, "0X", changeSpeed);
var btn1:PushButton = new PushButton(this, 10, 30, "0.25X", changeSpeed);
var btn2:PushButton = new PushButton(this, 10, 50, "0.5X", changeSpeed);
var btn3:PushButton = new PushButton(this, 10, 70, "1X", changeSpeed);
var btn4:PushButton = new PushButton(this, 10, 90, "2X", changeSpeed);
var btn5:PushButton = new PushButton(this, 10, 110, "4X", changeSpeed);
btn0.width =
btn1.width =
btn2.width =
btn3.width =
btn4.width =
btn5.width = 50;
}
//main loop
private var matrix:Matrix = new Matrix(0.5, 0, 0, 0.5);
private var point:Point = new Point(0, 0);
private var blur:BlurFilter = new BlurFilter(8, 8, 2);
private var darken:ColorTransform = new ColorTransform(1, 1, 1, 0.95);
private var lighten:ColorTransform = new ColorTransform(4, 4, 4);
private function mainLoop(e:Event):void {
emitter.step();
fader.colorTransform(fader.rect, darken);
fader.draw(canvas);
glow.draw(fader, matrix);
glow.applyFilter(glow, glow.rect, point, blur);
glow.colorTransform(glow.rect, lighten);
canvas.fillRect(canvas.rect, 0);
}
//shoots out a seed
private function tick(e:TimerEvent = null):void {
clock.impulse();
}
//changes playback speed
private function changeSpeed(e:Event):void {
var btn:PushButton = e.target as PushButton;
if (btn.label == "0X") {
emitter.actions.active = false;
emitter.active = false;
timer.stop();
darken.alphaMultiplier = 1;
return;
}
timer.start();
emitter.actions.active = true;
emitter.active = true;
var dt:Number;
switch (btn.label) {
case "0.25X": dt = 0.25; break;
case "0.5X": dt = 0.5; break;
case "1X": dt = 1; break;
case "2X": dt = 2; break;
case "4X": dt = 4; break;
}
emitter.stepTimeInterval = dt;
timer.delay = 1500 / dt;
darken.alphaMultiplier = Math.pow(0.95, dt);
}
}
}
//------------------------------------------------------------------------------------------------
import flash.display.BitmapData;
import flash.display.Shape;
import flash.events.Event;
import idv.cjcat.stardust.common.actions.Action;
import idv.cjcat.stardust.common.actions.Age;
import idv.cjcat.stardust.common.actions.AlphaCurve;
import idv.cjcat.stardust.common.actions.CompositeAction;
import idv.cjcat.stardust.common.actions.DeathLife;
import idv.cjcat.stardust.common.actions.ScaleCurve;
import idv.cjcat.stardust.common.actions.triggers.DeathTrigger;
import idv.cjcat.stardust.common.clocks.Clock;
import idv.cjcat.stardust.common.emitters.Emitter;
import idv.cjcat.stardust.common.events.EmitterEvent;
import idv.cjcat.stardust.common.initializers.Alpha;
import idv.cjcat.stardust.common.initializers.CollisionRadius;
import idv.cjcat.stardust.common.initializers.Color;
import idv.cjcat.stardust.common.initializers.CompositeInitializer;
import idv.cjcat.stardust.common.initializers.Life;
import idv.cjcat.stardust.common.initializers.Mask;
import idv.cjcat.stardust.common.initializers.Mass;
import idv.cjcat.stardust.common.math.Random;
import idv.cjcat.stardust.common.math.StardustMath;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.common.particles.Particle;
import idv.cjcat.stardust.common.renderers.Renderer;
import idv.cjcat.stardust.twoD.actions.Damping;
import idv.cjcat.stardust.twoD.actions.Gravity;
import idv.cjcat.stardust.twoD.actions.Move;
import idv.cjcat.stardust.twoD.actions.Spawn;
import idv.cjcat.stardust.twoD.actions.StardustSpriteUpdate;
import idv.cjcat.stardust.twoD.display.StardustSprite;
import idv.cjcat.stardust.twoD.emitters.Emitter2D;
import idv.cjcat.stardust.twoD.fields.UniformField;
import idv.cjcat.stardust.twoD.geom.MotionData2D;
import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass;
import idv.cjcat.stardust.twoD.initializers.Position;
import idv.cjcat.stardust.twoD.initializers.Velocity;
import idv.cjcat.stardust.twoD.particles.Particle2D;
import idv.cjcat.stardust.twoD.zones.LazySectorZone;
import idv.cjcat.stardust.twoD.zones.SectorZone;
import idv.cjcat.stardust.twoD.zones.SinglePoint;
//------------------------------------------------------------------------------------------------
const COMMON_MASK :int = 1;
const SEED_MASK :int = 2;
const STREAK_MASK :int = 4;
const FIREWORKS_MASK :int = 8;
const SPARK_MASK :int = 16;
const SEED_ANGLE :Number = 10;
const SEED_LIFE :Number = 125;
const SEED_SPEED_1 :Number = 3;
const SEED_SPEED_2 :Number = 4.5;
const SEED_COLOR :uint = 0xFFFFFF;
const SEED_RADIUS :Number = 3;
const SEED_MASS :Number = 1;
const STREAK_COUNT :int = 15;
const STREAK_LIFE :Number = 10;
const STREAK_SPEED :Number = 4;
const STREAK_SPEED_V :Number = 4; //variation
const STREAK_COLOR :Number = 0x9FFFFF;
const STREAK_RADIUS :Number = 2;
const STREAK_MASS :Number = 10;
const FIREWORKS_COUNT :Number = 12;
const FIREWORKS_SPEED :Number = 1.5;
const FIREWORKS_SPEED_V :Number = 1.5; //variation
const FIREWORKS_LIFE :Number = 70;
const FIREWORKS_LIFE_V :Number = 20; //variation
const FIREWORKS_COLOR_1 :uint = 0x4466AA;
const FIREWORKS_COLOR_2 :uint = 0x9966FF;
const FIREWORKS_DAMPING :Number = 0.01;
const FIREWORKS_RADIUS :Number = 3;
const FIREWORKS_MASS :Number = 2;
const SPARK_COUNT :Number = 5;
const SPARK_SPEED :Number = 1;
const SPARK_SPEED_V :Number = 1; //variation
const SPARK_LIFE :Number = 30;
const SPARK_LIFE_V :Number = 10; //variation
const SPARK_COLOR_1 :uint = 0xFF8033;
const SPARK_COLOR_2 :uint = 0x993311;
const SPARK_DAMPING :Number = 0.035;
const SPARK_RADIUS :Number = 3;
const SPARK_MASS :Number = 1;
//------------------------------------------------------------------------------------------------
class FireworksEmitter extends Emitter2D {
public var actions:CompositeAction;
public function FireworksEmitter(clock:Clock) {
super(clock);
//initializers
addInitializer(new SeedInitializers());
//actions
actions = new CompositeAction();
actions.checkComponentMasks = true;
actions.addAction(new CommonActions());
actions.addAction(new SeedActions());
actions.addAction(new StreakActions());
actions.addAction(new FireworksActions());
actions.addAction(new SparkActions());
addAction(actions);
}
}
//------------------------------------------------------------------------------------------------
class SeedInitializers extends CompositeInitializer {
public function SeedInitializers() {
addInitializer(new Mask(SEED_MASK | COMMON_MASK));
var sector:SectorZone = new SectorZone();
sector.minRadius = SEED_SPEED_1;
sector.maxRadius = SEED_SPEED_2;
sector.minAngle = -SEED_ANGLE - 90;
sector.maxAngle = SEED_ANGLE - 90;
addInitializer(new Life(new UniformRandom(SEED_LIFE, 0)));
addInitializer(new Position(new SinglePoint(232.5, 465)));
addInitializer(new Velocity(sector));
addInitializer(new Color(SEED_COLOR));
addInitializer(new CollisionRadius(SEED_RADIUS));
addInitializer(new Mass(new UniformRandom(SEED_MASS, 0)));
}
}
//------------------------------------------------------------------------------------------------
class StreakSpawn extends Spawn {
public function StreakSpawn(count:Random) {
super(count);
addInitializer(new Mask(STREAK_MASK | COMMON_MASK));
addInitializer(new Color(STREAK_COLOR));
addInitializer(new Life(new UniformRandom(STREAK_LIFE, 0)));
addInitializer(new Velocity(new LazySectorZone(STREAK_SPEED, STREAK_SPEED_V)));
addInitializer(new CollisionRadius(STREAK_RADIUS));
addInitializer(new Mass(new UniformRandom(STREAK_MASS, 0)));
}
}
//------------------------------------------------------------------------------------------------
class FireworksSpawn extends Spawn {
public function FireworksSpawn(count:Random) {
super(count);
addInitializer(new Mask(FIREWORKS_MASK | COMMON_MASK));
addInitializer(new DisplayObjectClass(ColorFader, [FIREWORKS_COLOR_1, FIREWORKS_COLOR_2]));
addInitializer(new Life(new UniformRandom(FIREWORKS_LIFE, FIREWORKS_LIFE_V)));
addInitializer(new Velocity(new LazySectorZone(FIREWORKS_SPEED, FIREWORKS_SPEED_V)));
addInitializer(new CollisionRadius(FIREWORKS_RADIUS));
addInitializer(new Mass(new UniformRandom(FIREWORKS_MASS, 0)));
}
}
//------------------------------------------------------------------------------------------------
class SparkSpawn extends Spawn {
public function SparkSpawn(count:Random) {
super(count);
addInitializer(new Mask(SPARK_MASK | COMMON_MASK));
addInitializer(new DisplayObjectClass(ColorFader, [SPARK_COLOR_1, SPARK_COLOR_2]));
addInitializer(new Life(new UniformRandom(SPARK_LIFE, SPARK_LIFE_V)));
addInitializer(new Velocity(new LazySectorZone(SPARK_SPEED, SPARK_SPEED_V)));
addInitializer(new CollisionRadius(SPARK_RADIUS));
addInitializer(new Mass(new UniformRandom(SPARK_MASS, 0)));
}
}
//------------------------------------------------------------------------------------------------
class CommonActions extends CompositeAction {
public function CommonActions() {
mask = COMMON_MASK;
var gravity:Gravity = new Gravity();
var field:UniformField = new UniformField(0, 0.025);
field.massless = false;
gravity.addField(field);
addAction(new Age());
addAction(new DeathLife());
addAction(new Move());
addAction(new StardustSpriteUpdate());
addAction(gravity);
}
}
//------------------------------------------------------------------------------------------------
class SeedActions extends CompositeAction {
public function SeedActions() {
mask = SEED_MASK;
priority = -2;
var trigger:DeathTrigger = new DeathTrigger();
trigger.addAction(new FireworksSpawn(new UniformRandom(FIREWORKS_COUNT, 0)));
trigger.addAction(new StreakSpawn(new UniformRandom(STREAK_COUNT, 0)));
addAction(new ScaleCurve(SEED_LIFE * 0.5, 0));
addAction(trigger);
}
}
//------------------------------------------------------------------------------------------------
class StreakActions extends CompositeAction {
public function StreakActions() {
mask = STREAK_MASK;
priority = -1;
addAction(new ScaleCurve(0.5 * STREAK_LIFE, 0.5 * STREAK_LIFE));
addAction(new AlphaCurve(0, 0.25 * STREAK_LIFE));
}
}
//------------------------------------------------------------------------------------------------
class FireworksActions extends CompositeAction {
public function FireworksActions() {
mask = FIREWORKS_MASK;
priority = -1;
var trigger:DeathTrigger = new DeathTrigger();
trigger.addAction(new SparkSpawn(new UniformRandom(SPARK_COUNT, 0)));
var sc:ScaleCurve = new ScaleCurve(SPARK_LIFE, 0);
sc.inScale = 0.25;
addAction(sc);
addAction(new Damping(FIREWORKS_DAMPING));
addAction(trigger);
}
}
//------------------------------------------------------------------------------------------------
class SparkActions extends CompositeAction {
public function SparkActions() {
mask = SPARK_MASK;
var sc:ScaleCurve = new ScaleCurve(SPARK_LIFE, 0);
sc.inScale = 0.25;
addAction(sc);
addAction(new Damping(SPARK_DAMPING));
}
}
//------------------------------------------------------------------------------------------------
class LineRenderer extends Renderer {
private var shape:Shape = new Shape();
private var target:BitmapData;
public function LineRenderer(target:BitmapData) {
this.target = target;
}
override protected function render(e:EmitterEvent):void {
if (!target) return;
var md:MotionData2D;
target.lock();
for each (var p:Particle2D in e.particles) {
if (!p.dictionary[this]) {
md = new MotionData2D(p.x, p.y);
p.dictionary[this] = md;
continue;
}
md = p.dictionary[this] as MotionData2D;
shape.graphics.clear();
shape.graphics.lineStyle(p.scale * p.collisionRadius * 2, p.color, p.alpha);
shape.graphics.moveTo(md.x, md.y);
shape.graphics.lineTo(p.x, p.y);
target.draw(shape);
md.x = p.x;
md.y = p.y;
}
target.unlock();
}
}
//------------------------------------------------------------------------------------------------
class ColorFader extends StardustSprite {
private var INIT_R :Number;
private var INIT_G :Number;
private var INIT_B :Number;
private var FINAL_R :Number;
private var FINAL_G :Number;
private var FINAL_B :Number;
public function ColorFader(color1:uint, color2:uint) {
INIT_R = (color1 & 0xFF0000) >> 16;
INIT_G = (color1 & 0x00FF00) >> 8;
INIT_B = (color1 & 0x0000FF);
FINAL_R = (color2 & 0xFF0000) >> 16;
FINAL_G = (color2 & 0x00FF00) >> 8;
FINAL_B = (color2 & 0x0000FF);
}
//this class only modifies the particle color, not displaying anything
override public function update(emitter:Emitter, particle:Particle, time:Number):void {
var t:Number = particle.initLife - particle.life;
var r:Number = StardustMath.interpolate(0, INIT_R, particle.initLife, FINAL_R, t);
var g:Number = StardustMath.interpolate(0, INIT_G, particle.initLife, FINAL_G, t);
var b:Number = StardustMath.interpolate(0, INIT_B, particle.initLife, FINAL_B, t);
particle.color = (r << 16) | (g << 8) | b;
}
}