package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.BlendMode; import flash.display.GradientType; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; /** * ボクセルの練習 * サイトを見て真似てみたが、ここまででチカラツキタ。 * クリックで作り直す。 * http://lab.parkstudio.ru/terra/ * @author jc at bk-zen.com */ [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="120")] public class Voxel extends Sprite { private var bmp: Bitmap; private var data: BitmapData; private var texA: BitmapData; private var texB: BitmapData; private var mapA: BitmapData; private var mapB: BitmapData; private var ycount: int = 0; private var matrix:Matrix; private var colorTf: ColorTransform; public function Voxel() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // bmp = new Bitmap(null); var sh: Shape = new Shape(); var m: Matrix = new Matrix(); m.createGradientBox(2, 200, - 90 * Math.PI / 180, 0, 0); sh.graphics.beginGradientFill(GradientType.LINEAR, [0x003366, 0x99CCFF, 0xEEEEB1, 0xDDDDA0, 0x71E817, 0x285300, 0xFFFFFF], [1, 1, 1, 1, 1, 1, 1], [0x00, 0x30, 0x32, 0x35, 0x3A, 0x60, 0xB0], m ); sh.graphics.drawRect(0, 0, 2, 200); data = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xFF6699FF); bmp.bitmapData = data; addChild(bmp); stage.addEventListener(MouseEvent.CLICK, onClick); mapA = new BitmapData(2, 200); mapA.draw(sh); m.createGradientBox(2, 200, 90 * Math.PI / 180, 0, 0); sh.graphics.clear(); sh.graphics.beginGradientFill(GradientType.LINEAR, [0x211F0F, 0xDCCA8F, 0xA38A53, 0xA68A52, 0x24150E, 0x24150E, 0xFA4900, 0xFFE900], [1, 1, 1, 1, 1, 1, 1, 1], [0x00, 0x05, 0x10, 0x20, 0x45, 0x70, 0x90, 0xA0], m ); sh.graphics.drawRect(0, 0, 2, 200); mapB = new BitmapData(2, 200); mapB.draw(sh); texA = new BitmapData(200, 200, false); texB = new BitmapData(200, 200, false); colorTf = new ColorTransform(1, 1, 1, 1, -50, -50, -50); start(); } private function onClick(e:MouseEvent):void { data.fillRect(data.rect, 0xFF6699FF); ycount = 0; start(); } private function start(): void { texA.perlinNoise(220, 220, 1 , Math.random() * 0xFFFF, false, true, 3, true, [new Point(- 50, -50)]); texB.perlinNoise(220, 220, 10, Math.random() * 0xFFFF, false, false, 7, true); texA.draw(texB, new Matrix(), null, BlendMode.OVERLAY, texA.rect, true); addEventListener(Event.ENTER_FRAME, onEnter); } private function onEnter(e: Event): void { if (ycount >= texA.height) { removeEventListener(Event.ENTER_FRAME, onEnter); return; } var n: int = texA.width; var i: int; var h: int = 0; var bh: int = 0; var r: int = 0; var g: int = 0; var b: int = 0; var rect: Rectangle = new Rectangle(); var color: uint; matrix = new Matrix(); rect.width = 1; data.lock(); while (++i < n) { h = (texA.getPixel(i, ycount) & 0xFF) / 0xFF * 200; color = mapA.getPixel(1, 200 - h); if (bh > h) { r = (color >> 16) & 0xFF; g = (color >> 8 ) & 0xFF; b = (color ) & 0xFF; r = Math.max(0, r - (10 - bh + h)); g = Math.max(0, g - (10 - bh + h)); b = Math.max(0, b - (10 - bh + h)); color = (r << 16) | (g << 8) | b; } rect.x = i + ycount + 30; rect.y = ((ycount + 570 - i) >> 1) - h; rect.height = h; if (i == 1 || ycount == texA.height - 1) { matrix.tx = rect.x; matrix.ty = rect.y; data.draw(mapB, matrix, (ycount == texA.height - 1 ? colorTf : null), null, rect); } else data.fillRect(rect, color | 0xFF000000); bh = h; } data.unlock(); ycount++; } } } Voxel