flash on 2012-1-30

by tjoen
♥0 | Line 138 | Modified 2012-01-30 07:22:29 | MIT License
play

ActionScript3 source code

/**
 * Copyright tjoen ( http://wonderfl.net/user/tjoen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/niYZ
 */

package  {
    
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.geom.ColorTransform;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.Point;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.display.Shape;
    
    public class ScrollingPerlinNoise extends Sprite {
        
        public var numOctaves:int;
        public var skyColor:uint;
        public var cloudsHeight:int;
        public var cloudsWidth:int;
        public var periodX:Number;
        public var periodY:Number;
        public var scrollAmountX:int;
        public var scrollAmountY:int;
        public var cloudsBitmapData:BitmapData;
        private var cloudsBitmap:Bitmap;
        private var cmf:ColorMatrixFilter;
        private var colorBackground:Shape;
        private var displayWidth:Number;
        private var displayHeight:Number;
        private var seed:int;
        private var sliceDataH:BitmapData;
        private var sliceDataV:BitmapData;
        private var sliceDataCorner:BitmapData;
        private var horizCutRect:Rectangle;
        private var vertCutRect:Rectangle;
        private var cornerCutRect:Rectangle;
        private var horizPastePoint:Point;
        private var vertPastePoint:Point;
        private var cornerPastePoint:Point;
        private var origin:Point;
        private var cloudsMask:Shape;
        private var grayScale:Boolean;
        
        public function ScrollingPerlinNoise(w:int = 300, h:int = 200, scrollX:int = 0, scrollY:int = -4, useBG:Boolean = true, col:uint = 0x000000, nOctaves:Number = 5, perlinPeriodX:Number = 150, perlinPeriodY:Number = 150, gray:Boolean = true) {
            
            displayWidth = w;
            displayHeight = h;
            //the code can be modified so that the clouds are bigger than the display
            cloudsWidth = displayWidth;
            cloudsHeight = displayHeight;
            periodX = perlinPeriodX;
            periodY = perlinPeriodY;
            scrollAmountX = scrollX;
            scrollAmountY = scrollY;
            grayScale = gray;
            
            numOctaves = nOctaves;
            
            skyColor = col;
                
            cloudsBitmapData = new BitmapData(cloudsWidth,cloudsHeight,true);
            cloudsBitmap = new Bitmap(cloudsBitmapData);
                
            origin = new Point(0,0);
                        
            if (useBG) {
                colorBackground = new Shape();
                colorBackground.graphics.beginFill(skyColor);
                colorBackground.graphics.drawRect(0,0,displayWidth,displayHeight);
                colorBackground.graphics.endFill();
                
                this.addChild(colorBackground);
            }
            this.addChild(cloudsBitmap);
            
            /*
            //use a mask if the clouds are made to be bigger than the display
            cloudsMask = new Shape();
            cloudsMask.graphics.beginFill(0xFFFFFF);
            cloudsMask.graphics.drawRect(0,0,displayWidth,displayHeight);
            cloudsMask.graphics.endFill();
            this.addChild(cloudsMask);
            cloudsBitmap.mask = cloudsMask;
            */
            
            makeClouds();
            setRectangles();
        }
        
        public function startScroll():void {
            this.addEventListener(Event.ENTER_FRAME, onEnter);
        }
        public function stopScroll():void {
            this.removeEventListener(Event.ENTER_FRAME, onEnter);
        }
                
        private function setRectangles():void {
            
            if (scrollAmountX != 0) {
                sliceDataV = new BitmapData(Math.abs(scrollAmountX), cloudsHeight - Math.abs(scrollAmountY), true);
            }
            if (scrollAmountY != 0) {
                sliceDataH = new BitmapData(cloudsWidth, Math.abs(scrollAmountY), true);
            }
            if ((scrollAmountX != 0)&&(scrollAmountY != 0)) {
                sliceDataCorner = new BitmapData(Math.abs(scrollAmountX), Math.abs(scrollAmountY), true);
            }
            horizCutRect = new Rectangle(0, cloudsHeight - scrollAmountY, cloudsWidth - Math.abs(scrollAmountX), Math.abs(scrollAmountY));
            vertCutRect = new Rectangle(cloudsWidth - scrollAmountX, 0, Math.abs(scrollAmountX), cloudsHeight - Math.abs(scrollAmountY));
            cornerCutRect = new Rectangle(cloudsWidth - scrollAmountX, cloudsHeight - scrollAmountY,Math.abs(scrollAmountX), Math.abs(scrollAmountY));
            
            horizPastePoint = new Point(scrollAmountX, 0);
            vertPastePoint = new Point(0, scrollAmountY);
            cornerPastePoint = new Point(0, 0);
            
            if (scrollAmountX < 0) {
                cornerCutRect.x = vertCutRect.x = 0;
                cornerPastePoint.x = vertPastePoint.x = cloudsWidth + scrollAmountX;
                horizCutRect.x = -scrollAmountX;
                horizPastePoint.x = 0;
            }
            if (scrollAmountY < 0) {
                cornerCutRect.y = horizCutRect.y = 0;
                cornerPastePoint.y = horizPastePoint.y = cloudsHeight + scrollAmountY;
                vertCutRect.y = -scrollAmountY;
                vertPastePoint.y = 0;
            }
            
        }
        
        public function makeClouds():void {
            seed = int(Math.random()*0xFFFFFF);
                    
            //draw clouds
            if (grayScale) {
                cloudsBitmapData.perlinNoise(periodX,periodY,numOctaves,seed,true,true,1,true);    
            }
            else {
                cloudsBitmapData.perlinNoise(periodX,periodY,numOctaves,seed,true,true,7,false);    
            }
            
            //alpha adjust
            var alphaAdjust:ColorMatrixFilter = new ColorMatrixFilter([1,0,0,0,0,
                                                                       0,1,0,0,0,
                                                                       0,0,1,0,0,
                                                                       1,0,0,0,0]);
            
            cloudsBitmapData.applyFilter(cloudsBitmapData, cloudsBitmapData.rect, new Point(), alphaAdjust);

            
        }
        
        private function onEnter(evt:Event):void {
            cloudsBitmapData.lock();
            
            //copy to buffers the part that will be cut off
            if (scrollAmountX != 0) {
                sliceDataV.copyPixels(cloudsBitmapData, vertCutRect, origin);
            }
            if (scrollAmountY != 0) {
                sliceDataH.copyPixels(cloudsBitmapData, horizCutRect, origin);
            }
            if ((scrollAmountX != 0)&&(scrollAmountY != 0)) {
                sliceDataCorner.copyPixels(cloudsBitmapData, cornerCutRect, origin);
            }
            
            //scroll
            cloudsBitmapData.scroll(scrollAmountX, scrollAmountY);
            
            //draw the buffers on the opposite sides
            if (scrollAmountX != 0) {
                cloudsBitmapData.copyPixels(sliceDataV, sliceDataV.rect, vertPastePoint);
            }
            if (scrollAmountY != 0) {
                cloudsBitmapData.copyPixels(sliceDataH, sliceDataH.rect, horizPastePoint);
            }
            if ((scrollAmountX != 0)&&(scrollAmountY != 0)) {
                cloudsBitmapData.copyPixels(sliceDataCorner, sliceDataCorner.rect, cornerPastePoint);
            }
                        
            cloudsBitmapData.unlock();
        }


    }
    
}