forked from: forked from: [Stardust] Brilliant Fireworks - forked from: Creek challenge

by tamac124 forked from forked from: [Stardust] Brilliant Fireworks - forked from: Creek challenge (diff: 5)
♥0 | Line 326 | Modified 2013-04-18 23:13:53 | MIT License
play

ActionScript3 source code

/**
 * Copyright tamac124 ( http://wonderfl.net/user/tamac124 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/IWKl
 */

// forked from kurosuke's forked from: [Stardust] Brilliant Fireworks - forked from: Creek challenge
// 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;
            }
            */
            dt=1;
            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;
    }
}