In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

法線マップ×お絵かき×ストリーム×パーティクル×重力

以前作った「法線マップ×お絵かき×ストリーム」をForkして、パーティクル化しつつ重力を加えたもの。
/**
 * Copyright o_healer ( http://wonderfl.net/user/o_healer )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/a3ds
 */

// forked from o_healer's 法線マップ×お絵かき×ストリーム
/*
 「法線マップ×お絵かき×ストリーム×パーティクル×重力」

 長い!

 以前作った「法線マップ×お絵かき×ストリーム」をパーティクル化して高速化しつつ、
 さらに重力を組み合わせてみた。
*/

package {
    import flash.display.Sprite;
    import flash.events.*;
 
    public class FlashTest extends Sprite {
        public function FlashTest() {
            // write as3 code here..
            addChild(new GameMain());
        }
    }
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.*;
import flash.filters.*;

internal class GameMain extends Sprite{
    //==Const==

    //Effect
/*
    static public const FILTER_GLOW:ConvolutionFilter = new ConvolutionFilter(
        3,3,
        [
            0.0, 0.1, 0.0,
            0.1, 0.5, 0.1,
            0.0, 0.1, 0.0
        ]
    );
/*/
    static public const GLOW_BLUR:int = 6;//2
    static public const FILTER_GLOW:BlurFilter = new BlurFilter(GLOW_BLUR, GLOW_BLUR);
//*/

    //Utility
    static public const POS_ZERO:Point = new Point(0,0);

    //==Var==

    //法線マップ保持用(そしてそのまま描画)
    public var m_BitmapData_Nrm:BitmapData;

    //パーティクル描画用
    public var m_BitmapData_View:BitmapData;

    //煌きエフェクト用
    public var m_BitmapData_Glow:BitmapData;

    //パーティクル用レイヤー
    public var m_Layer_Particle:Sprite = new Sprite();


    //==Func==

    public function GameMain(){
        //Init Later (for Using "stage" etc.)
        addEventListener(Event.ADDED_TO_STAGE, Init);
    }
    
    public function Init(e:Event = null):void{
        //Init Once Only
        {
            removeEventListener(Event.ADDED_TO_STAGE, Init);
        }

        var W:int = stage.stageWidth;
        var H:int = stage.stageHeight;

        //Create Bitmap
        {
            m_BitmapData_Nrm  = new BitmapData(W, H, false, Vector_to_Color(new Vector3D(0,0,1)));
            m_BitmapData_View = new BitmapData(W, H, true, 0x00000000);
            m_BitmapData_Glow = new BitmapData(W, H, true, 0x00000000);

            addChild(new Bitmap(m_BitmapData_Nrm));
            addChild(new Bitmap(m_BitmapData_View));

            var bmp_glow:Bitmap = new Bitmap(m_BitmapData_Glow, PixelSnapping.NEVER, true);
            bmp_glow.blendMode = BlendMode.ADD;
            addChild(bmp_glow);
        }

        //Draw Nrm By Mouse
        {
            var draw_flag:Boolean = false;

            var mouseX_Old:int = 0;
            var mouseY_Old:int = 0;

            var shape:Shape = new Shape();
            var g:Graphics = shape.graphics;
            {
                shape.filters = [
                    new BlurFilter()
                ];
            }

            //Draw
            var draw:Function = function(in_X:int, in_Y:int, in_OldX:int, in_OldY:int):void{
                //Nrm
                var vec:Vector3D;
                {
                    const BASE_Z:Number = 10.0;

                    vec = new Vector3D(
                        in_X - in_OldX,
                        -(in_Y - in_OldY),
                        BASE_Z
                    );

                    vec.normalize();
                }

                //Nrm => Color
                var nrm_color:uint;
                {
                    nrm_color = Vector_to_Color(vec);
                }

                //draw circle
                {
                    const RAD:uint = 20;

                    g.clear();
                    g.lineStyle(RAD, nrm_color, 1.0);

                    g.moveTo(in_OldX, in_OldY);
                    g.lineTo(in_X, in_Y);

                    m_BitmapData_Nrm.draw(shape);
                }
            };

            //Down
            addEventListener(
                MouseEvent.MOUSE_DOWN,
                function(e:MouseEvent):void{
                    //Flag On
                    {
                        draw_flag = true;
                    }

                    //Mouse Pos
                    {
                        mouseX_Old = mouseX;
                        mouseY_Old = mouseY;
                    }

                    //Draw Nrm
                    {
                        draw(mouseX, mouseY, mouseX_Old, mouseY_Old);
                    }
                }
            );
            
            //Move
            stage.addEventListener(
                MouseEvent.MOUSE_MOVE,
                function(e:MouseEvent):void{
                    //Check
                    {
                        if(! draw_flag){
                            return;
                        }
                    }

                    //Draw Nrm
                    {
                        draw(mouseX, mouseY, mouseX_Old, mouseY_Old);
                    }

                    //Mouse Pos
                    {
                        mouseX_Old = mouseX;
                        mouseY_Old = mouseY;
                    }
                }
            );

            //Up
            stage.addEventListener(
                MouseEvent.MOUSE_UP,
                function(e:MouseEvent):void{
                    //Flag Off
                    {
                        draw_flag = false;
                    }
                }
            );
        }

        //Create Obj
        {
            const Num:int = 1000;

            addChild(m_Layer_Particle);
            for(var i:int = 0; i < Num; i++){
                m_Layer_Particle.addChild(new PointObject(W*Math.random(), H*Math.random(), m_BitmapData_View, m_BitmapData_Nrm));
            }
        }

        //Call "Update"
        {
            addEventListener(Event.ENTER_FRAME, Update);
        }
    }

    public function Update(e:Event):void{
        //Clear
        m_BitmapData_View.fillRect(m_BitmapData_View.rect, 0x00000000);

        //Draw
        var num:int = m_Layer_Particle.numChildren;
        for(var i:int = 0; i < num; i++){
            (m_Layer_Particle.getChildAt(i) as PointObject).Update();
        }

        //Effect
        m_BitmapData_Glow.applyFilter(m_BitmapData_Glow, m_BitmapData_Glow.rect, POS_ZERO, FILTER_GLOW);
        m_BitmapData_Glow.draw(m_BitmapData_View);
    }

    //Utility
    static public function Vector_to_Color(in_Nrm:Vector3D):uint{
        var color:uint;
        {
            var r:uint = 0xFE * (0.5 + 0.5*in_Nrm.x);
            var g:uint = 0xFE * (0.5 + 0.5*in_Nrm.y);
            var b:uint = 0xFE * (0.5 + 0.5*in_Nrm.z);

            color = (r << 16) | (g << 8) | (b << 0);
        }

        return color;
    }
}

class PointObject extends Sprite
{
    //const
    static public const RAD:int = 5;
    static public const VEL:int = 10;

    static public const PARTICLE_COLOR:uint = 0xFFFFFFFF;

    //var
    public var m_BitmapData_View:BitmapData;
    public var m_BitmapData_Nrm:BitmapData;
    public var m_Vel:Vector3D = new Vector3D(0, 0);

    //Init
    public function PointObject(in_X:int, in_Y:int, in_BitmapData_View:BitmapData, in_BitmapData_Nrm:BitmapData){
        //Pos
        {
            this.x = in_X;
            this.y = in_Y;
        }

        //外部データ
        {
            m_BitmapData_View = in_BitmapData_View;
            m_BitmapData_Nrm  = in_BitmapData_Nrm;
        }
/*
        //Graphic
        {
            var shape:Shape = new Shape();
            {//Draw Circle
                var g:Graphics = shape.graphics;
                g.beginFill(0xFFFFFF, 1.0);
                g.drawCircle(0, 0, RAD);
            }
            {//Add Filter
                shape.filters = [
                    new BlurFilter(),
                    new GlowFilter(0xFFFFFF)
                ];
            }

            addChild(shape);
        }

        //Call "Update"
        {
            addEventListener(Event.ENTER_FRAME, Update);
        }
//*/
    }

    public function Update(e:Event=null):void{
        //法線マップから得られる速度
        var NrmColor:uint;
        var NrmVel:Vector3D;
        {
            NrmColor = m_BitmapData_Nrm.getPixel(this.x, this.y);
            NrmVel = Color_to_Vector(NrmColor);
            NrmVel.scaleBy(VEL);
        }

        var ratio:Number = 1 - NrmVel.z/VEL;//速度指定がないようなら今の速度を維持する

        //現在の速度とマージ
        {
//            var ratio:Number = 0.1;

            m_Vel.x = lerp(m_Vel.x, NrmVel.x, ratio);
            m_Vel.y = lerp(m_Vel.y, NrmVel.y, ratio);

            if(this.y > m_BitmapData_View.height*3/4){
                if(m_Vel.y > 0){m_Vel.y = 0;}
            }else{
                m_Vel.y += 0.1;
            }
        }

        //Move
        var OldX:int;
        var OldY:int;
        var NewX:int;
        var NewY:int;
        {
            OldX = this.x;
            OldY = this.y;

            this.x += m_Vel.x;
            this.y += m_Vel.y;

            NewX = this.x;
            NewY = this.y;

            if(this.x < 0){this.x += m_BitmapData_View.width;}
            if(this.x >= m_BitmapData_View.width){this.x -= m_BitmapData_View.width;}
            if(this.y < 0){this.y = 0;}
            if(this.y >= m_BitmapData_View.height){this.y -= m_BitmapData_View.height;}
        }

        //Draw
        {
            m_BitmapData_View.setPixel32(this.x, this.y, PARTICLE_COLOR);
            //m_BitmapData_View.setPixel32(this.x, this.y, NrmColor | 0xFF000000);
            //m_BitmapData_View.setPixel32((NewX+OldX)>>1, (NewY+OldY)>>1, PARTICLE_COLOR);//ついでに中間地点にも点を置いてみる
        }
    }

    //Utility
    static public function Color_to_Vector(in_Color:uint):Vector3D{
        var dir:Vector3D;
        {
            dir = new Vector3D(
                2 * ((in_Color >> 16) & 0xFF) / 254.0 - 1,
                -(2 * ((in_Color >>  8) & 0xFF) / 254.0 - 1),
                2 * ((in_Color >>  0) & 0xFF) / 254.0 - 1
            );
        }

        return dir;
    }

    public function lerp(in_Src:Number, in_Dst:Number, in_Ratio:Number):Number{
        return (in_Src * (1 - in_Ratio)) + (in_Dst * in_Ratio);
    }
}