Beautifl - Flash Gallery

Thumbnail : [Stardust] Particle on Mouse Position
[Stardust] Particle on Mouse Position
clockmaker 2010-01-04 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;

    import idv.cjcat.stardust.common.clocks.ImpulseClock;
    import idv.cjcat.stardust.common.emitters.Emitter;
    import idv.cjcat.stardust.common.renderers.Renderer;
    import idv.cjcat.stardust.threeD.papervision3d.renderers.PV3DParticleRenderer;

    import org.papervision3d.core.geom.Particles;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.ViewportLayer;
    /**
     * スターダストを使った、3Dパーティクルデモ
     * @author yasu
     */
    [SWF(width=465, height=465, frameRate=30, backgroundColor=0)]
    public class Main extends BasicView {

        private static const COLOR_PARTICLE:uint = 0x8844FF;
        private static const NUM_PARTICLE:uint = 4;

        private var clock:ImpulseClock; // 時計
        private var emitter:Emitter; // エミッター
        private var particleRenderer:Renderer; // レンダラー

        private var particles:Particles = new Particles(); // パーティクルのラッパー
        private var isMouseDown:Boolean = false; // マウスを押してるかのフラグ
        private var viewportLayerForParticle:ViewportLayer; // ビューポートレイヤー

        // エフェクト用
        private var canvas:BitmapData;
        private var mtx:Matrix;
        private const effectColorTr:ColorTransform = new ColorTransform(0.95, 0.95, 1, 0.9, 10, 10, 10);
        private const effectFilter:BlurFilter = new BlurFilter(4, 4, 2);
        private const effectPoint:Point = new Point();

        // コンストラクタ
        public function Main() {
            // 地面を作成
            var earth:Plane = new Plane(new WireframeMaterial(0xFFFFFF, 0.2), 500, 500, 6, 6);
            earth.rotationX = 90;
            earth.y = -75;
            scene.addChild(earth);

            // カメラを等倍ピクセルに表示できる位置に配置
            camera.z = -camera.zoom * camera.focus;

            // 3Dのパーツを配置
            scene.addChild(particles);
            viewportLayerForParticle = particles.createViewportLayer(viewport, true);

            // 時計を作成
            clock = new ImpulseClock(NUM_PARTICLE);

            // パーティクルシステムの構築
            emitter = new MyEmitter(COLOR_PARTICLE, clock);
            particleRenderer = new PV3DParticleRenderer(particles);
            particleRenderer.addEmitter(emitter);

            // エフェクト用のビットマップデータ
            canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
            addChild(new Bitmap(canvas));

            // キャプチャ用変換マトリックス
            mtx = new Matrix();
            mtx.translate(stage.stageWidth / 2, stage.stageHeight / 2);

            // エンターフレームイベントの登録
            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);

            startRendering(); // レンダリング
            opaqueBackground = 0x0; // 背景色
            stage.quality = StageQuality.MEDIUM; //画質を低に
        }

        // エンターフレームイベント
        private function loop(e:Event):void {
            // マウスを押していたらパーティクル発生
            if (isMouseDown)
                clock.impulse();

            // エミッターの更新
            emitter.step();

            // マウスの位置に調整
            MyEmitter(emitter).point.x = mouseX - viewport.width / 2;
            MyEmitter(emitter).point.y = -(mouseY - viewport.height / 2);

            canvas.draw(viewportLayerForParticle, mtx, null, BlendMode.ADD);
            canvas.colorTransform(canvas.rect, effectColorTr);
            canvas.applyFilter(canvas, canvas.rect, effectPoint, effectFilter);
        }

        private function upHandler(e:MouseEvent):void {
            isMouseDown = false;
        }

        private function downHandler(e:MouseEvent):void {
            isMouseDown = true;
        }
    }
}


import idv.cjcat.stardust.common.actions.*;
import idv.cjcat.stardust.common.clocks.*;
import idv.cjcat.stardust.common.initializers.*;
import idv.cjcat.stardust.common.math.*;
import idv.cjcat.stardust.threeD.actions.*;
import idv.cjcat.stardust.threeD.deflectors.*;
import idv.cjcat.stardust.threeD.emitters.*;
import idv.cjcat.stardust.threeD.fields.*;
import idv.cjcat.stardust.threeD.initializers.*;
import idv.cjcat.stardust.threeD.papervision3d.initializers.*;
import idv.cjcat.stardust.threeD.zones.*;

import org.papervision3d.materials.special.ParticleMaterial;

/**
 * カスタムエミッター
 * @author yasu
 */
class MyEmitter extends Emitter3D {
    public var point:SinglePoint3D = new SinglePoint3D(); // パーティクルの発生位置

    public function MyEmitter(color:uint, clock:Clock = null) {
        super(clock);

        // -----------------------------
        // パーティクルの属性を定義
        // -----------------------------
        addInitializer(new Position3D(point)); // 発生位置
        // マテリアル
        var mat:ParticleMaterial = new ParticleMaterial(color, 1, ParticleMaterial.SHAPE_CIRCLE, 6);
        addInitializer(new PV3DParticle([mat]));
        addInitializer(new Life(new UniformRandom(60, 20)));
        // 力方向
        var cap:SphereCap = new SphereCap(0, 0, 0, 5, 10, 20);
        cap.rotationX = 180;
        addInitializer(new Velocity3D(cap));

        // -----------------------------
        // パーティクルのアクションを定義
        // -----------------------------
        addAction(new Age()); // 寿命を有効化
        addAction(new DeathLife()); // 消えるを有効化
        addAction(new Accelerate3D(0.1)); // 加速を有効化
        addAction(new Move3D()); // 移動を有効化
        addAction(new ScaleCurve(5, 20));
        // 重力
        var field:UniformField3D = new UniformField3D(0, -1, 0);
        var gravity:Gravity3D = new Gravity3D();
        gravity.addField(field);
        addAction(gravity);
        // 反射
        var deflect:Deflect3D = new Deflect3D();
        deflect.addDeflector(new PlaneDeflector(0, -75, 0, 0, 1, 0));
        addAction(deflect);
    }
}