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

法線マップ×お絵かき×ストリーム

法線マップで遊ぶための試作。
 マウスで法線マップを描き、その法線の向きに沿って点が動く。
Get Adobe Flash player
by o_healer 12 Jul 2010
/**
 * 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/eRhl
 */

/*
 法線マップで遊ぶための試作。
 マウスで法線マップを描き、その法線の向きに沿って点が動く。
*/

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==


    //==Var==

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


    //==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 = new BitmapData(W, H, false, Vector_to_Color(new Vector3D(0,0,1)));

            addChild(new Bitmap(m_BitmapData));
        }

        //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.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 = 100;

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

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

    public function Update(e:Event):void{
    }

    //Utility
    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;

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

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

        //Nrm
        {
            m_BitmapData = in_BitmapData;
        }

        //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 NrmVel:Vector3D;
        {
            NrmVel = Color_to_Vector(m_BitmapData.getPixel(this.x, this.y));
            NrmVel.scaleBy(VEL);
        }

        //現在の速度とマージ
        {
//            var ratio:Number = 0.1;
            var ratio:Number = 1 - NrmVel.z/VEL;//速度指定がないようなら今の速度を維持する

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

        //Move
        {
            this.x += m_Vel.x;
            this.y += m_Vel.y;

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

    //Utility
    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);
    }
}