Fireworks3D
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dQOF
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
[SWF(width = 465, height = 465, backgroundColor = 0x0, frameRate = 60)]
/**
* ...
* @author lizhi
*/
public class Fireworks3D extends Sprite {
private var cm:Matrix3D = new Matrix3D();
private var cvm:Matrix3D = new Matrix3D();
private var m:Matrix3D = new Matrix3D();
private var vm:Matrix3D = new Matrix3D();
private var p:PerspectiveProjection = new PerspectiveProjection();
private var pm:Matrix3D;
private var vins:Vector.<Number> = new Vector.<Number>();
private var vouts:Vector.<Number> = new Vector.<Number>();
private var uvts:Vector.<Number> = new Vector.<Number>();
private var v2ds:Vector.<Number> = new Vector.<Number>();
private var view:Shape = new Shape();
private var bmd:BitmapData = new BitmapData(465, 465, false, 0);
private var particles:Array = [];
public function Fireworks3D() {
pm = p.toMatrix3D();
addEventListener(Event.ENTER_FRAME, render);
stage.addEventListener(MouseEvent.CLICK, onClick);
addChild(new Bitmap(bmd));
addChild(view);
view.x = 228;
view.y = 228;
stage.quality = "low";
}
private function onClick(e:Event=null):void {
explode((Math.random()-0.5)*400, (Math.random()-0.5)*400, (Math.random()-0.5)*400, 0xffffff*Math.random());
}
private function randomColorComp():int {
return Math.random() < .3?0xff * (.7 + .3 * Math.random()):0;
}
private var t:int = 0;
private function render(e:Event):void {
if (Math.random()<0.05) {
onClick();
}
cm.identity();
cm.appendTranslation(0, 200, -550);
cm.appendRotation(view.mouseX/10, Vector3D.Y_AXIS,cm.position);
cm.appendRotation(-view.mouseY/10, Vector3D.X_AXIS,cm.position);
cvm.rawData = cm.rawData;
cvm.invert();
vm.rawData = m.rawData;
vm.append(cvm);
view.graphics.clear();
for (var i:int = particles.length - 1; i >= 0; i--){
var p:particle = particles[i];
p.vx *= p.deceleration;
p.vy *= p.deceleration;
p.vz *= p.deceleration;
p.vy += p.gravity;
p.position.x = p.position.x + p.vx;
p.position.y = p.position.y + p.vy;
p.position.z = p.position.z + p.vz;
p.energy *= p.deceleration;
if (p.energy < 0.05){
particles.splice(i, 1);
} else {
p.vposition = vm.transformVector(p.position);
p.v2d = Utils3D.projectVector(pm, p.vposition);
view.graphics.moveTo(p.v2d.x, p.v2d.y);
var c:int = 0;
var tc:int = 6;
for (var j:int = p.tails.length - 1; j >= 0; j--,c++) {
if (c>p.energy*tc) {
p.tails.splice(j, 1);
continue;
}
var v:Vector3D = p.tails[j];
var vp:Vector3D = vm.transformVector(v);
var v2d:Vector3D = Utils3D.projectVector(pm, vp);
if (Math.random()<.5) {
view.graphics.lineStyle(0, p.color);
view.graphics.lineTo(v2d.x, v2d.y);
}else {
view.graphics.moveTo(v2d.x, v2d.y);
}
}
if (p.tails[0]) {
v = p.tails[p.tails.length - 1];
if (Math.sqrt((v.x-p.position.x)*(v.x-p.position.x)+(v.y-p.position.y)*(v.y-p.position.y)+(v.z-p.position.z)*(v.z-p.position.z))>p.length) {
p.tails.push(p.position.clone());
}
}else {
p.tails.push(p.position.clone());
}
}
}
var ct:Number=.9
bmd.colorTransform(bmd.rect, new ColorTransform(ct,ct,ct));
bmd.applyFilter(bmd, bmd.rect, new Point, new BlurFilter(2,2));
bmd.draw(view,view.transform.matrix);
}
private function explode(x:Number, y:Number, z:Number, color:uint):void {
var c:int = 400*Math.random();
while (c-- > 0){
var p:particle = new particle;
p.energy = Math.random() * 5;
var m:Matrix3D = new Matrix3D();
m.appendTranslation(0, 0,(Math.random()*.2+0.8) * 5);
m.appendRotation(360 * Math.random(), Vector3D.X_AXIS);
m.appendRotation(360 * Math.random(), Vector3D.Y_AXIS);
var v:Vector3D = m.transformVector(new Vector3D);
p.vx = v.x;
p.vy = v.y;
p.vz = v.z;
p.position = new Vector3D(x, y, z);
p.color = color;
p.deceleration = 0.95;
p.gravity = 0.05;
p.length = 2;
particles.push(p);
}
}
}
}
import flash.geom.Vector3D;
class particle {
public var tails:Array = [];
public var vx:Number;
public var vy:Number;
public var vz:Number;
public var position:Vector3D;
public var vposition:Vector3D;
public var v2d:Vector3D;
public var energy:Number;
public var color:uint;
public var deceleration:Number;
public var gravity:Number;
public var length:Number;
}