Beautifl - Flash Gallery

Thumbnail : [Stardust] キラキラの3Dパーティクル
[Stardust] キラキラの3Dパーティクル
clockmaker 2009-12-22 MIT License

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

package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Matrix;
    
    import idv.cjcat.stardust.common.clocks.SteadyClock;
    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.core.math.Number3D;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.ViewportLayer;
    
    import net.hires.debug.*;

    /**
     * スターダストを使った、3Dパーティクルデモ
     * 詳細はこちらを参考ください
     * http://clockmaker.jp/blog/2009/12/as3-stardust/
     * @author yasu
     */    
    [SWF(width=465, height=465, frameRate=60)]
    public class KiraKiraParticle extends BasicView {
        // コンストラクタ
        public function KiraKiraParticle() {

            // PV3Dのパーティクル
            particles = new Particles();
            // ビューポートレイヤーにすると、ビットマップデータの加工がやりやすいよ
            viewportLayerForParticle = particles.createViewportLayer(viewport);
            scene.addChild(particles);
            
            //地面
            earth = new Plane(new WireframeMaterial(0x999999, .5), 5000, 5000, 6, 6)
            earth.y = -500;
            earth.rotationX = 90;
            scene.addChild(earth);

            // パーティクルシステムの構築
            emitter = new MyEmitter(new SteadyClock(3)); // エミッターに1フレームに発生させたい数値を指定
            particleRenderer = new PV3DParticleRenderer(particles);
            particleRenderer.addEmitter(emitter);

            // エンターフレームイベントの登録
            addEventListener(Event.ENTER_FRAME, loop);

            // 背景
            opaqueBackground = 0x0;
            stage.quality = StageQuality.LOW; //画質を低に
            
            // キラキラロジック
            canvas = new BitmapData(465 / 4, 465 / 4, false, 0x000000);
            var bmp:Bitmap = new Bitmap(canvas, PixelSnapping.NEVER, false);
            bmp.scaleX = bmp.scaleY = 4;
            bmp.smoothing = true;
            bmp.blendMode = BlendMode.ADD;
            addChild(bmp);
            mtx = new Matrix();
            mtx.translate(-viewport.width / 2, -viewport.height / 2);
            mtx.scale(0.25, 0.25);
            mtx.translate(viewport.width / 4, viewport.height / 4);
        }
        // キラキラ
        private var canvas:BitmapData;
        // 地面
        private var earth:Plane;
        // エミッター
        private var emitter:Emitter;
        // レンダラー
        private var particleRenderer:Renderer;
        // パーティクルのラッパー
        private var particles:Particles;
        //モーションの角度
        private var rot:Number = 0;
        // ビューポート
        private var viewportLayerForParticle:ViewportLayer;
        // キラキラのキャプチャ変換行列
        private var mtx:Matrix;
        // エンターフレームイベント
        private function loop(e:Event):void {
            rot += 3;

            // 円周上を動いているかのようにみせる
            MyEmitter(emitter).point.x = 400 * Math.sin(rot * Number3D.toRADIANS);
            MyEmitter(emitter).point.y = 300;
            MyEmitter(emitter).point.z = 300 * Math.cos(rot * Number3D.toRADIANS);

            // パーティクルの方向を変える
            MyEmitter(emitter).sphereCap.rotationX = 90;
            MyEmitter(emitter).sphereCap.rotationZ = -rot - 90;

            // カメラをマウス座標にする
            camera.x += (1000 * Math.sin(mouseX / stage.stageWidth * Math.PI * 2) - camera.x) * 0.1;
            camera.y += (600 * mouseY / stage.stageHeight - camera.y) * 0.1;
            camera.z += (1000 * Math.cos(mouseX / stage.stageWidth * Math.PI * 2) - camera.z) * 0.1;

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

            // Papervision3Dのレンダリング
            singleRender();
            
            // キラキラ
            canvas.fillRect(canvas.rect, 0x0);
            canvas.draw(viewportLayerForParticle, mtx);            
        }
    }
}


import idv.cjcat.stardust.common.actions.Age;
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.initializers.Life;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.threeD.actions.Accelerate3D;
import idv.cjcat.stardust.threeD.actions.Move3D;
import idv.cjcat.stardust.threeD.emitters.Emitter3D;
import idv.cjcat.stardust.threeD.initializers.Position3D;
import idv.cjcat.stardust.threeD.initializers.Velocity3D;
import idv.cjcat.stardust.threeD.papervision3d.initializers.PV3DParticle;
import idv.cjcat.stardust.threeD.zones.SinglePoint3D;
import idv.cjcat.stardust.threeD.zones.SphereCap;

import org.papervision3d.materials.special.ParticleMaterial;

/**
 * カスタムエミッター
 * @author yasu
 */
class MyEmitter extends Emitter3D {
    public var point:SinglePoint3D = new SinglePoint3D(); // パーティクルの発生位置
    public var sphereCap:SphereCap = new SphereCap(0, 0, 0, 1, 0, 40); // パーティクルの拡散
    public function MyEmitter(clock:Clock = null) {
        super(clock);
        
        // マテリアル
        var mat:ParticleMaterial = new ParticleMaterial(0xFFCCBB, 1, 1, 6);
        
        // パーティクルの属性を定義
        addInitializer(new Position3D(point)); // 発生位置
        addInitializer(new PV3DParticle([mat]));
        addInitializer(new Life(new UniformRandom(120, 0)));
        addInitializer(new Velocity3D(sphereCap));
        
        // パーティクルのアクションを定義
        addAction(new Age()); // 寿命を有効化
        addAction(new DeathLife()); // 消えるを有効化
        addAction(new Accelerate3D(0.05)); // 加速を有効化
        addAction(new Move3D()); // 移動を有効化
        addAction(new ScaleCurve(20, 20)); //スケール変更を有効化
    }
}