package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Graphics; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.Event; import flash.geom.Rectangle; import flash.utils.ByteArray; public class Main extends Sprite { //ビットマップの大きさ private var cWidth:int = 200; private var cHeight:int = 200; //ビットマップデータ private var bmp_data:BitmapData; private var field1:Array; //2ステップ前の水面の高さ private var field2:Array; //1ステップ前の水面の高さ private var field3:Array; //現在の水面の高さ private var counter:int = 0; private var startSize:uint = 4; private var startHeight:uint = 1024; public function Main():void { init(); } private function init():void { var i:int; var j:int; bmp_data = new BitmapData(cWidth, cHeight, false, 0x000000); var bmp:Bitmap = new Bitmap(bmp_data); stage.addChild(bmp); field1 = new Array(cWidth * cHeight); field2 = new Array(cWidth * cHeight); field3 = new Array(cWidth * cHeight); for (j = 0; j < cHeight; j++) { for (i = 0; i < cWidth; i++) { field1[i + j * cWidth] = field2[i + j * cWidth] = 0; //配列field1とfield2を初期化 } } stage.addEventListener(MouseEvent.MOUSE_DOWN, onMDown); stage.addEventListener(Event.ENTER_FRAME, run); } private function run(event:Event):void { var isView:Boolean = (counter % 2) == 0; var iMax:int = cWidth * cHeight - cWidth - 1; var i:int; var j:int; var k:int; for (i = cWidth + 1; i < iMax; i++) { var wx:int = i % cWidth; //wxの範囲は0~cWidth-1 var wy:int = (i - wx) / cWidth; //wyの範囲は0~cWidth-1 if (wx == 0 || wx == cWidth - 1) //左端または右端 { continue; } //※最重要※ field3[i] = ((((field2[i - 1] + field2[i + 1] + field2[i - cWidth] + field2[i + cWidth]) >> 1) - field1[i]) * 63) >> 6; if (isView) { var a:int = ((field2[i] - field2[i - cWidth - 1]) >> 8) + 128; if (a > 255) { a = 255; } else if (a < 0) { a = 0; } bmp_data.setPixel(wx, wy, a); } } counter++; var field0:Array = new Array; field0 = field1; field1 = field2; field2 = field3; field3 = field0; } private function onMDown(event:MouseEvent):void { var mx:int = event.stageX; var my:int = event.stageY; raiseWave(mx, my); } private function raiseWave(cx:int, cy:int):void { var field:Array = new Array(); var j:int; var sx:int; var sy:int; //キーポイント field = field2; if (cx < startSize || cx > cWidth - 1 - startSize || cy < startSize || cy > cHeight - 1 - startSize) { return; } for (sx = -startSize; sx < startSize; sx++) { for (sy = -startSize; sy < startSize; sy++) { var r:Number = sx * sx + sy * sy; var ad:int = (sx + cx) + (sy + cy) * cWidth; if (r < startSize * startSize) { field[ad] += (int)((Math.cos(Math.sqrt(r) / startSize * Math.PI) + 1) * 256 * startHeight); } } } } } }