/* 以前の水面ゆらゆらを円状にしました。 波は前回とは別のごまかし方法を採用。あいかわらずインチキ波 マウスのインタラクションはとりあえず無し。 */ 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 ); } } 水面ゆらゆらを円に