forked from: 【AS100本ノック】8回目:水
AS100本ノック
* 8回目のお題は「水」
* あなたなりの「水」を表現してください。
↓cda244さんの水面ゆらゆら
http://wonderfl.net/code/4c69cea8a30ffe8449400323c4f4431cd2c1ef85
とQuasimondさんのAquaGalss Effect(AS)
http://www.quasimondo.com/archives/000561.php
を使わせてもらってます。オリジナルの部分はほとんどありません。
すいません。ありがとうございます。
/**
* Copyright mex_md ( http://wonderfl.net/user/mex_md )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pRuq
*/
// forked from mex's 【AS100本ノック】8回目:水
/*
* AS100本ノック
* 8回目のお題は「水」
* あなたなりの「水」を表現してください。
*/
//↓cda244さんの水面ゆらゆら
//http://wonderfl.net/code/4c69cea8a30ffe8449400323c4f4431cd2c1ef85
//とQuasimondさんのAquaGalss Effect(AS)
//http://www.quasimondo.com/archives/000561.php
//を使わせてもらってます。オリジナルの部分はほとんどありません。
//すいません。ありがとうございます。
package
{
import caurina.transitions.Tweener;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.GradientType;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.BevelFilter;
import flash.filters.BlurFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DropShadowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.utils.Timer;
import flash.system.LoaderContext;
public class FlashTest extends Sprite
{
private const imgURL:String = "http://assets.wonderfl.net/images/related_images/2/28/2829/2829f459079fe1f1e7dc4c9a220ff2f015104ba7"
public const W:int = 465;
public const H:int = 465
private const PADDING:int = 10;
private const ZERO:Point = new Point(0, 0);
private var mat:Matrix;
private const RECT:Rectangle = new Rectangle(0, 0, W, H);
private var displaceFilter:DisplacementMapFilter;
private var blurFilter:BlurFilter;
private var base:Loader;
private var baseBMD:BitmapData;
private var drop:Sprite;
private var drop2:Bitmap;
private var drop3:Sprite;
private var tempMap:BitmapData;
private var displaceMap:BitmapData;
private var mergeMap:BitmapData;
////
public const NUM:uint=300; //頂点数
private const MOUSE_DIFF_RATIO:Number=1; // (0<) 大きい程マウスに反応する
private const AUTO_INTERVAL:uint = 3000; //オート波が起きる間隔 msec
private var vertexes:Array=[]; //頂点
private var mdlPt:Array=[]; //頂点の中点
//頂点の基本波からの位相差分
// 0:マウス
// 1:オート
private var diffPt:Array=[[], []];
//波が起こるインデックス
// 0:マウス
// 1:オート
private var startIndex:Array=[0,0];
private var mouseOldY:int;
private var mouseNewY:int;
private var mouseDiff:Number = 0;
private var mouseDiffGoal:Number= 0;
private var autoTimer:Timer;
private var autoDiff:Number = 0;
////
public function FlashTest()
{
blurFilter = new BlurFilter(2, 2, 1);
//mat = new Matrix(1, 0, 0, 1, PADDING * 0.5, PADDING * 0.5);
mat = new Matrix(1, 0, 0, 1,0,0);
base = new Loader();
base.contentLoaderInfo.addEventListener(Event.COMPLETE, onBaseLoaded);
var context:LoaderContext = new LoaderContext(true);
base.load(new URLRequest(imgURL),context);
////
for(var i:uint=0; i<NUM; i++){
var vertex:Vertex=new Vertex( i, this );
vertexes.push( vertex );
//中点作成
if(i>1){
mdlPt.push( new Point( (vertexes[i-1].x+vertexes[i].x)*0.5, (vertexes[i-1].y+vertexes[i].y)*0.5 ) );
}
//差分
diffPt[0].push( 0 );
diffPt[1].push( 0 );
}
mouseNewY = mouseY;
if(mouseNewY < 0){ mouseNewY = 0; }
else if(mouseNewY > H){ mouseNewY = H; }
mouseOldY = mouseNewY;
}
/*-----------------------------------------//
//onBaseLoaded
//------------------------------------------*/
private function onBaseLoaded(evt:Event):void
{
this.addChild(base);
baseBMD = new BitmapData(W, H, true, 0x0000ff);
var mat:Matrix = new Matrix();
mat.scale(1.05, 1.05);
mat.translate(-12,-12)
baseBMD.draw(base,mat);
//drop
drop = new Sprite();
drop.graphics.beginFill(0x808080);
drop.graphics.drawCircle(25, 25, 25);
//drop.graphics.drawRect(25,400,100,100);
drop.graphics.endFill();
drop.alpha = 0.7;
this.addChild(drop);
//tempMap = new BitmapData(drop.width + PADDING, drop.height + PADDING, true, 0x00808080);
tempMap = new BitmapData(W,H,true, 0x00808080);
//displaceMap = new BitmapData(drop.width + PADDING, drop.height + PADDING, false, 0x00808080);
displaceMap = new BitmapData(W, H, false, 0x00808080);
//mergeMap = new BitmapData(drop.width + PADDING, drop.height + PADDING, true, 0x00808080);
mergeMap = new BitmapData(W,H, true, 0x00808080);
makeDrop();
drop2 = new Bitmap(mergeMap);
drop2.filters = [new DropShadowFilter(4, 45, 0x000000, 0.02, 8, 8, 0.3, 3, false, false, false)];
this.addChild(drop2);
////
addEventListener(Event.ENTER_FRAME, updateMouseDiff);
addEventListener(Event.ENTER_FRAME, updateWave);
autoTimer = new Timer(AUTO_INTERVAL);
autoTimer.addEventListener(TimerEvent.TIMER, generateAutoWave);
autoTimer.start();
//Tweener.addTween(displaceFilter, { scaleX:0, scaleY:0, time:5 });
}
/*-----------------------------------------//
//mouseDownHandler
//------------------------------------------*/
private function mouseDownHandler(evt:MouseEvent):void
{
drop.graphics.lineStyle(10, 0x808080, 1);
drop.graphics.beginFill(0x808080);
//drop.graphics.drawCircle(mouseX, mouseY, 25 * Math.random() + 10);
drop.graphics.lineTo(mouseX, mouseY);
drop.graphics.endFill();
makeDrop();
/*drop3.graphics.beginFill(0x808080);
drop3.graphics.drawCircle(mouseX, mouseY, 5);
drop3.graphics.endFill();*/
}
private function makeDrop():void
{
displaceFilter = new DisplacementMapFilter (displaceMap, ZERO,0, 1,12, 12,"wrap");
var bevel:BevelFilter = new BevelFilter (10, 10, 0xffffff,1, 0x000000, 1, 4,4, 3, 1, "inner");
drop.filters = [bevel];
tempMap.fillRect (tempMap.rect,0x00808080);
tempMap.draw (drop, mat, new ColorTransform (1, 0, 0, 1, 0, 0, 0, 0), "normal", null, true);
bevel.angle += 90;
drop.filters = [bevel];
tempMap.draw (drop,mat,new ColorTransform (0, 1, 0, 1, 0, 0, 0, 0),"add",null,true);
tempMap.applyFilter (tempMap,tempMap.rect,ZERO,blurFilter);
displaceMap.draw (tempMap);
}
/*-----------------------------------------//
//enterFrameHandler
//------------------------------------------*/
private function enterFrameHandler(evt:Event):void
{
var rect:Rectangle = new Rectangle (0,0, W,H);
mergeMap.copyPixels (baseBMD,rect,ZERO);
rect.x = rect.y = 0;
mergeMap.applyFilter (mergeMap,rect,ZERO,new BlurFilter (2,2, 2));
mergeMap.applyFilter (mergeMap,rect,ZERO,displaceFilter);
mergeMap.copyChannel (tempMap,tempMap.rect,ZERO,8,8);
}
////
private function generateAutoWave(tEvt:TimerEvent):void
{
autoDiff = 100;
startIndex[1] = Math.round( Math.random()*(NUM-1) );
}
//--------------------------------------
// マウスY座標の差を計算
//--------------------------------------
private function updateMouseDiff(evt:Event):void
{
mouseOldY = mouseNewY;
mouseNewY = mouseY;
if(mouseNewY < 0){ mouseNewY = 0; }
else if(mouseNewY > H){ mouseNewY =H; }
mouseDiffGoal = (mouseNewY - mouseOldY) * MOUSE_DIFF_RATIO;
}
//---------------------------------------
// 各種更新
//---------------------------------------
private function updateWave(evt:Event):void
{
drop.graphics.clear();
//それぞれの波の減衰
mouseDiff -= (mouseDiff - mouseDiffGoal)*0.3;
autoDiff -= autoDiff*0.3;
//-------------------------------------
//波の基点
//-------------------------------------
//マウス波
var mX:int = mouseX;
if(mX < 0){ mX = 0; }
else if(mX > W-2){ mX = W-2; } //-2はみ出さないための保険
startIndex[0] = 1+Math.floor( (NUM-2) * mX / W );
diffPt[0][startIndex[0]] -= ( diffPt[0][startIndex[0]] - mouseDiff )*0.99;
//オート波
//diffPt[1][startIndex[1]] -= ( diffPt[1][startIndex[1]] - autoDiff )*0.99;
var i:int;
//-------------------------------------
//差分更新
//-------------------------------------
//マウス波
//左側
var d:uint;
for(i=startIndex[0]-1; i >=0; i--){
d = startIndex[0] - i;
if(d>15){ d=15; }
diffPt[0][i] -= ( diffPt[0][i] - diffPt[0][i+1] )*(1-0.01*d);
}
//右側
for(i=startIndex[0]+1; i < NUM; i++){
d = i - startIndex[0];
if(d>15){ d=15; }
diffPt[0][i] -= ( diffPt[0][i] - diffPt[0][i-1] )*(1-0.01*d);
}
//オート波
//左側
/*for(i=startIndex[1]-1; i >=0; i--){
d = startIndex[1] - i;
if(d>15){ d=15; }
diffPt[1][i] -= ( diffPt[1][i] - diffPt[1][i+1] )*(1-0.01*d);
}
//右側
for(i=startIndex[1]+1; i < NUM; i++){
d = i - startIndex[1];
if(d>15){ d=15; }
diffPt[1][i] -= ( diffPt[1][i] - diffPt[1][i-1] )*(1-0.01*d);
}*/
//-------------------------------------
//各頂点更新
//-------------------------------------
for(i=0; i < NUM; i++){ vertexes[i].uodatePos( diffPt[0][i]+diffPt[1][i] ); }
//-------------------------------------
//中点更新
//-------------------------------------
for(i=0; i < NUM-2; i++){ mdlPt[i].y = (vertexes[i+1].y + vertexes[i+2].y)*0.5; }
drawWave();
mergeMap.copyPixels (baseBMD,RECT,ZERO);
mergeMap.applyFilter (mergeMap,RECT,ZERO,new BlurFilter (2,2, 2));
mergeMap.applyFilter (mergeMap,RECT,ZERO,displaceFilter);
mergeMap.copyChannel (tempMap,tempMap.rect,ZERO,8,8);
}
//---------------------------------------
// 描画
//---------------------------------------
private function drawWave():void
{
drop.graphics.beginFill(0x808080, 1);
drop.graphics.moveTo(W, H);
drop.graphics.lineTo(0, H);
drop.graphics.lineTo( vertexes[0].x, vertexes[0].y);
drop.graphics.curveTo( vertexes[1].x, vertexes[1].y, mdlPt[0].x, mdlPt[0].y);
for(var i:uint=2; i<NUM-2; i++){
drop.graphics.curveTo( vertexes[i].x, vertexes[i].y, mdlPt[i-1].x, mdlPt[i-1].y);
}
drop.graphics.curveTo( vertexes[NUM-2].x, vertexes[NUM-2].y, vertexes[NUM-1].x, vertexes[NUM-1].y);
drop.graphics.endFill();
makeDrop();
}
}
}
class Vertex
{
static const BASE_Y:uint = 350;
static const BASE_R:uint = 10;
static const PI:Number = Math.PI;
static const FRICTION:Number = 0.1;
static const DECELERATION:Number = 0.95;
static const SPEED_OF_BASE_WAVE:uint = 2;
private var theta:uint=0;
private var goalY:Number=0;
private var amp:Number=0;
public var x:Number;
public var y:Number;
public function Vertex(prmID:uint, parent:Object):void
{
theta = 360 * prmID/( parent.NUM-1) ;
x = prmID * parent.W / (parent.NUM-1);
y = BASE_Y + BASE_R * Math.sin( theta * PI /180 );
}
public function uodatePos(diffVal:Number):void
{
theta += SPEED_OF_BASE_WAVE;
if( theta>=360 ){ theta -= 360; }
goalY = BASE_Y + BASE_R * Math.sin( theta * PI /180 );
goalY += diffVal;
amp += goalY - y;
y += amp * FRICTION;
amp *= DECELERATION;
}
}