法線マップ×お絵かき×ストリーム×パーティクル×重力
以前作った「法線マップ×お絵かき×ストリーム」を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);
}
}