flash as3 3d烟花效果实现代码

作者:袖梨 2022-06-28
 代码如下 复制代码
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.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 = 30)]
    /**
     * ...
     * @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. = new Vector.();
        private var vouts:Vector. = new Vector.();
        private var uvts:Vector. = new Vector.();
        private var v2ds:Vector. = new Vector.();
 
        private var view2:Sprite = new Sprite();
        private var view:Shape = new Shape();
        private var bmd:BitmapData = new BitmapData(465, 465, true, 0);
        private var particles:Array = [];
 
        public function Fireworks3D() {
            pm = p.toMatrix3D();
            addEventListener(Event.ENTER_FRAME, render);
            stage.addEventListener(MouseEvent.CLICK, onClick);
            addChild(view);
            //addChild(new Bitmap(bmd));
            view.x = 228;
            view.y = 228;
        }
 
        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 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.lineStyle(400 / p.v2d.w, p.color);
                    view.graphics.moveTo(p.v2d.x, p.v2d.y);
                    var c:int = 0;
                    var tc:int = 4;
                    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);
                        view.graphics.lineStyle(500 / p.v2d.w, p.color,(p.energy*tc-c)/p.energy*tc);
                        view.graphics.lineTo(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());
                    }
                }
            }
            //bmd.colorTransform(bmd.rect, new ColorTransform(0.095, 0.095, 0.095, 0.095));
            //bmd.applyFilter(bmd, bmd.rect, new Point, new BlurFilter());
            //bmd.draw(view2);
        }
 
        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;
}

相关文章

精彩推荐