![Thumbnail : [Stardust] Spiky Ball](https://d12wcjmk7c4d40.cloudfront.net/archives/6f4932bae1a01983cfa20ace03f702b0f9c4deaf.jpg)
/** * 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.Sprite; import flash.events.Event; import flash.events.MouseEvent; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.math.StardustMath; import idv.cjcat.stardust.threeD.renderers.DisplayObjectRenderer3D; [SWF(backgroundColor="#FFFFFF", frameRate=60)] public class Main extends Sprite { private var emitter:SpikeEmitter; private var renderer:DisplayObjectRenderer3D; public function Main():void { //container var container:Sprite = new Sprite(); container.x = container.y = 232.5; addChild(container); //emitter & renderer emitter = new SpikeEmitter(new SteadyClock(1)); renderer = new DisplayObjectRenderer3D(container); renderer.addEmitter(emitter); //pause button var pauseBtn:PushButton = new PushButton(); pauseBtn.x = pauseBtn.y = 10; pauseBtn.label = "Pause"; addChild(pauseBtn); pauseBtn.addEventListener(MouseEvent.CLICK, togglePause); stage.addEventListener(MouseEvent.MOUSE_MOVE, rotateCamera); addEventListener(Event.ENTER_FRAME, mainLoop); rotateCamera(); } private function mainLoop(e:Event):void { emitter.step(); } private function rotateCamera(e:Event = null):void { var theta:Number = 0.55 * (mouseX - 320) * StardustMath.DEGREE_TO_RADIAN; var phy:Number = 0.35 * (mouseY - 240) * StardustMath.DEGREE_TO_RADIAN; phy = StardustMath.clamp(phy, -0.45 * Math.PI, 0.45 * Math.PI); var r:Number = 1000; var x:Number = r * Math.sin(theta) * Math.cos(phy); var y:Number = r * Math.sin(phy); var z:Number = -r * Math.cos(theta) * Math.cos(phy); renderer.camera.position.x = x; renderer.camera.position.y = y; renderer.camera.position.z = z; renderer.camera.direction.set( -x, -y, -z); } private function togglePause(e:Event):void { var btn:PushButton = e.target as PushButton; if (btn.label == "Pause") { emitter.active = false; emitter.pausibleActions.active = false; btn.label = "Resume"; } else { emitter.active = true; emitter.pausibleActions.active = true; btn.label = "Pause"; } } } } //------------------------------------------------------------------------------------------------ import flash.display.Shape; import flash.geom.ColorTransform; import idv.cjcat.stardust.common.actions.Age; 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.clocks.Clock; import idv.cjcat.stardust.common.emitters.Emitter; import idv.cjcat.stardust.common.initializers.Life; 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.threeD.actions.BillboardOriented; import idv.cjcat.stardust.threeD.actions.CalculateScreenVelocity; import idv.cjcat.stardust.threeD.actions.Move3D; import idv.cjcat.stardust.threeD.actions.StardustSpriteUpdate3D; import idv.cjcat.stardust.threeD.emitters.Emitter3D; import idv.cjcat.stardust.threeD.initializers.DisplayObjectClass3D; import idv.cjcat.stardust.threeD.initializers.Velocity3D; import idv.cjcat.stardust.threeD.zones.SinglePoint3D; import idv.cjcat.stardust.threeD.zones.SphereShell; import idv.cjcat.stardust.threeD.zones.SphereSurface; import idv.cjcat.stardust.twoD.display.StardustSprite; import idv.cjcat.stardust.twoD.initializers.Position; //------------------------------------------------------------------------------------------------ //I have no idea why this line must be added in order to compile successfully on Wonderfl. //Just ignore this class :p class BugFixer extends Shape { public function BugFixer() { } } //------------------------------------------------------------------------------------------------ class SpikeEmitter extends Emitter3D { public var pausibleActions:CompositeAction; public function SpikeEmitter(clock:Clock) { super(clock); //initializers addInitializer(new DisplayObjectClass3D(Spike)); addInitializer(new Velocity3D(new SphereShell(0, 0, 0, 4, 5))); addInitializer(new Life(new UniformRandom(100, 20))); //actions pausibleActions = new CompositeAction(); pausibleActions.addAction(new Age()); pausibleActions.addAction(new DeathLife()); pausibleActions.addAction(new Move3D()); pausibleActions.addAction(new ScaleCurve(10, 20)); pausibleActions.addAction(new StardustSpriteUpdate3D()); addAction(pausibleActions); //these two actions cannot be paused //they must be executed non-stopped to properly update the billboards orientation addAction(new CalculateScreenVelocity()); addAction(new BillboardOriented()); } } //------------------------------------------------------------------------------------------------ class Spike extends StardustSprite { public static const WIDTH :Number = 100; public static const HEIGHT :Number = 150; public static const ONE_THIRD :Number = 1 / 3; public static const TWO_THIRD :Number = 2 / 3; public static const INIT_R :Number = 0xFF; public static const INIT_G :Number = 0xDD; public static const INIT_B :Number = 0x00; public static const FINAL_R :Number = 0xFF; public static const FINAL_G :Number = 0x77; public static const FINAL_B :Number = 0x00; public function Spike() { graphics.beginFill(0); graphics.moveTo(0, -HEIGHT * TWO_THIRD); graphics.lineTo(0.5 * WIDTH, HEIGHT * ONE_THIRD); graphics.lineTo( -0.5 * WIDTH, HEIGHT * ONE_THIRD); graphics.lineTo(0, -HEIGHT * TWO_THIRD); graphics.endFill(); draw(INIT_R, INIT_G, INIT_B); } 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); draw(r, g, b); } private var color:ColorTransform = new ColorTransform(); private function draw(r:int, g:int, b:int):void { color.redOffset = r; color.greenOffset = g; color.blueOffset = b; transform.colorTransform = color; } }