法線マップ×お絵かき×ストリーム
法線マップで遊ぶための試作。
マウスで法線マップを描き、その法線の向きに沿って点が動く。
/**
* 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);
}
}