forked from: 水面ゆらゆらを円に
以前の水面ゆらゆらを円状にしました。
波は前回とは別のごまかし方法を採用。あいかわらずインチキ波
マウスのインタラクションはとりあえず無し。
// forked from cda244's 水面ゆらゆらを円に
/*
以前の水面ゆらゆらを円状にしました。
波は前回とは別のごまかし方法を採用。あいかわらずインチキ波
マウスのインタラクションはとりあえず無し。
*/
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.geom.Point;
[SWF(width="300", height="300", backgroundColor="0x000000", frameRate="30")]
public class Wave extends MovieClip
{
public const STAGE_W:uint = 300;
public const STAGE_H:uint = 300;
public const NUM:uint=50; //頂点数
private const AUTO_INTERVAL:uint = 1500; //オート波が起きる間隔 msec
public var vertexes:Array=[]; //頂点
private var mdlPt:Array=[]; //頂点の中点
//頂点の基本波からの位相差分
// 0:マウス
// 1:オート
private var diffPt:Array=[[], []];
//波が起こるインデックス
// 0:マウス
// 1:オート
private var startIndex:Array=[0,0];
private var autoTimer:Timer;
private var autoDiff:Number = 0;
public function Wave():void
{
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 );
}
mdlPt.push( new Point( (vertexes[NUM-1].x+vertexes[0].x)*0.5, (vertexes[NUM-1].y+vertexes[0].y)*0.5 ) );
addEventListener(Event.ENTER_FRAME, updateWave);
startIndex[1] = uint(NUM*0.25);
autoTimer = new Timer(AUTO_INTERVAL);
autoTimer.addEventListener(TimerEvent.TIMER, generateAutoWave);
autoTimer.start();
}
private function generateAutoWave(tEvt:TimerEvent):void
{
autoDiff = 50;
startIndex[1] = uint( Math.random()*(NUM-1) );
//startIndex[1] = uint(NUM*0.75);
}
//---------------------------------------
// 各種更新
//---------------------------------------
private function updateWave(evt:Event):void
{
//それぞれの波の減衰
autoDiff -= autoDiff*0.1;
var i:int;
//-------------------------------------
//差分更新
//-------------------------------------
var d:uint;
var tmpIndex:int;
var prevIndex:int;
for(i=0; i <NUM-1; i++){ diffPt[1][i] = 0; }
diffPt[1][startIndex[1]] = autoDiff;
vertexes[startIndex[1]].uodatePos( autoDiff );
//外まわり
for(i=startIndex[1]+1; i <startIndex[1]+NUM*0.5; i++){
tmpIndex = i; if(i>NUM-1){ tmpIndex -= NUM; }
vertexes[tmpIndex].uodatePos( diffPt[0][tmpIndex]+diffPt[1][tmpIndex] );
}
//内まわり
for(i=startIndex[1]-1; i >startIndex[1]-NUM*0.5-1; i--){
tmpIndex = i; if(i<0){ tmpIndex += NUM; }
vertexes[tmpIndex].uodatePos( diffPt[0][tmpIndex]+diffPt[1][tmpIndex] );
}
//頂点
for(i=1; i<NUM; i++){
mdlPt[i-1].x = (vertexes[i-1].x + vertexes[i].x)*0.5;
mdlPt[i-1].y = (vertexes[i-1].y + vertexes[i].y)*0.5;
}
mdlPt[NUM-1].x = (vertexes[NUM-1].x + vertexes[0].x)*0.5;
mdlPt[NUM-1].y = (vertexes[NUM-1].y + vertexes[0].y)*0.5;
drawWave();
}
//---------------------------------------
// 描画
//---------------------------------------
private function drawWave():void
{
graphics.clear();
graphics.beginFill(0xFFFFFF, 1);
graphics.moveTo( mdlPt[NUM-1].x, mdlPt[NUM-1].y);
for(var i:uint=0; i<NUM; i++){
graphics.curveTo( vertexes[i].x, vertexes[i].y, mdlPt[i].x, mdlPt[i].y);
}
graphics.endFill();
}
}
}
class Vertex
{
static const C_X:uint =150;
static const C_Y:uint =150;
static const BASE_R:uint = 100;
static const PI:Number = Math.PI;
static const FRICTION:Number = 0.1;
static const DECELERATION:Number = 0.9;
public var x:Number;
public var y:Number;
private var rad:Number=0;
private var ampR:Number=0;
private var nextID:int;
private var prevID:int;
private var parent:Object;
private var goalR:Number=BASE_R;
internal var r:Number=BASE_R;
public function Vertex(prmID:uint, prmParent:Object):void
{
parent = prmParent;
nextID = prmID+1; if(nextID==parent.NUM){ nextID=0; }
prevID = prmID-1; if(prevID==-1){ prevID=parent.NUM-1; }
rad = 2 * PI * prmID / parent.NUM;
x = C_X + BASE_R * Math.cos( rad );
y = C_Y + BASE_R * Math.sin( rad );
}
public function uodatePos(diffVal:Number):void
{
if(diffVal != 0){
goalR = BASE_R + diffVal;
}
else{
goalR = (parent.vertexes[prevID].r+parent.vertexes[nextID].r)*0.5;
}
ampR += goalR - r;
r += ampR * FRICTION;
ampR *= DECELERATION;
x = C_X + r * Math.cos( rad );
y = C_Y + r * Math.sin( rad );
}
}