Beautifl - Flash Gallery

Thumbnail : Voxel
Voxel
bkzen 2009-09-04 All rights reserved

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

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++;
        }
    }
    
}