In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ShadowCast

using code from here: http://nemonon.de/blog/
But how can I load an image, another than this??
Get Adobe Flash player
by Albert 10 Dec 2015
/**
 * Copyright Albert ( http://wonderfl.net/user/Albert )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qO4O
 */

//using code from here: http://nemonon.de/blog/
//But how can I load an image, another than this??

package {
    import flash.display.Sprite;
        import flash.display.BitmapData;   
        import flash.display.Bitmap; 
      import flash.events.*;
     import flash.net.*;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.system.LoaderContext;
    import flash.geom.Rectangle;
    public class FlashTest extends Sprite {
        private var loader:Loader = new Loader(  );
        private var bd: BitmapData;
        private var bm2:Bitmap;
        public function FlashTest() {
            // write as3 code here..
            init();
        }

        
//         private static const URL:String = "http://assets.wonderfl.net/images/related_images/5/5f/5fd9/5fd907386c2c4584f449e1c10a37fc8d68fe7060";
        private static const URL:String = "http://farm4.static.flickr.com/3078/2328337281_ee32463b4e.jpg";
            private function init():void
        {
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE , complete);
            loader.load(new URLRequest(URL), new LoaderContext(true));
        }
        
        
        private function complete(e:Event):void 
        {
            var loaderInfo:LoaderInfo = e.target as LoaderInfo;
            
            loaderInfo.removeEventListener(Event.COMPLETE , complete);
            
            var bm:Bitmap = loaderInfo.content as Bitmap;
            var bmd:BitmapData = bm.bitmapData;
            ShadowCaster(bmd, true);
            var bmd2:BitmapData;
            fovData=null;
            bmd2=fovData;
            //blockedColor = 0xA0A0A0;
            bm2 = new Bitmap(bmd2);
            this.addChild(loaderInfo.content);
            this.addChild(bm2);
            bm2.alpha=0.1;
            getFOV(30,120);
            stage.addEventListener(MouseEvent.CLICK , onClick);
        }
        
        private function onClick(e:Event):void
        {
            bm2.alpha=0.8;
            clearFOV();
            getFOV(stage.mouseX, stage.mouseY);
        }
            
                    
    /**
     * Generates the FOV (field of view) of a pixel based map.
     * Imlements the shadow cast algorithm
     * Created by: Jörg Mehnert
     * Created at: 2010/01/07
     */

        // members
        // *******************************************************************************
        // the base data
        private var _worldMap:BitmapData;
        // the output data, containing the field of view
        private var _fovData:BitmapData;
        // specifies, whether the output data should be preserved or not
        private var _updateOutput:Boolean;
        // the color in the output data for the visible pixels
        private var _visibleColor:uint = 0xFFFFFF;
        // the color in the output data for the invisible pixels
        private var _invisibleColor:int = 0x000000;
        // the threshold color for the scan, pixel colors beneath this color will be invisible
        private var _blockedColor:uint = 0xAAAAAA;
        
        // rounded point of view coordinates to improve performance
        private var _ceiledPovX:int;
        private var _ceiledPovY:int;
        
        // constructor
        // *******************************************************************************
        /**
         * Constructor
         * @param givenWorldMap
         * @param preserveOutputData - default = false
         */
        public function ShadowCaster(givenWorldMap:BitmapData, preserveOutputData:Boolean = false):void {
            worldMap = givenWorldMap;
            _updateOutput = !preserveOutputData;
        }
        
        // getter/setter
        // *******************************************************************************
        /**
         * Gets the world map
         * @return BitmapData
         */
        public function get worldMap():BitmapData {
            return _worldMap;
        }
        
        /**
         * Sets the world map
         * @param newWorldMap
         */
        public function set worldMap(newWorldMap:BitmapData):void {
            if (newWorldMap == null) {
                throw new Error("World map (flash.display.BitmapData) cannot be null.");
            }
            _worldMap = newWorldMap;
            fovData = _fovData;
        }
        
        /**
         * Indicates, whether the output data should be preserved or not
         * @return Boolean
         */
        public function get isOutputUpdated():Boolean {
            return _updateOutput;
        }
        
        /**
         * Preserve the output data or not
         * @param value
         */
        public function set isOutputUpdated(value:Boolean):void {
            _updateOutput = value;
        }
        
        /**
         * Gets the output data
         * @return BitmapData
         */
        public function get fovData():BitmapData {
            return _fovData;
        }
        
        
        /**
         * Sets the output data
         * @param newFovData
         */
        public function set fovData(newFovData:BitmapData):void {
            if (newFovData == null) {
                _fovData = new BitmapData(_worldMap.width, _worldMap.height, false, _invisibleColor);
            } else {
                _fovData = newFovData;
            }
        }
        
        /**
         * Gets the visible color
         * @return uint
         */
        public function get visibleColor():uint {
            return _visibleColor;
        }
        
        /**
         * Sets the visible color. The default value is 0xFFFFFF
         * @param newColor
         */
        public function set visibleColor(newColor:uint):void {
            _visibleColor = newColor;
        }
        
        /**
         * Gets the invisible color
         * @return uint
         */
        public function get invisibleColor():uint {
            return _invisibleColor;
        }
        
        /**
         * Sets the invisible color. The default value is 0x000000
         * @param newColor
         */
        public function set invisibleColor(newColor:uint):void {
            _invisibleColor = newColor;
        }
        
        /**
         * Gets the blocked color
         * @return uint
         */
        public function get blockedColor():uint {
            return _blockedColor;
        }
        
        /**
         * Sets the blocked color. All pixel colors beneath this value will be interpreted as blocked.
         * The default value is 0xAAAAAA
         * @param newColor
         */
        public function set blockedColor(newColor:uint):void {
            _blockedColor = newColor;
        }
        
        // public methods
        // *******************************************************************************
        /**
         * Computes the field of view, based on the current world data and the given coordinates of the view point
         * @param viewPointX - the x coordinate of the view point
         * @param viewPointY - the y coordinate of the view point
         * @return BitmapData
         */
        public function getFOV(viewPointX:Number, viewPointY:Number):BitmapData {
            if (_updateOutput) {
                _fovData = new BitmapData(_worldMap.width, _worldMap.height, false, _invisibleColor);
            }
            if (viewPointX < 0 || viewPointX > _worldMap.width
                || viewPointY < 0 || viewPointY > _worldMap.height) {
                    trace("ShadowCaster: The view point is out of bounds. The midpoint of the world map is used instead.");
                    _ceiledPovX = Math.ceil(_worldMap.width / 2);
                    _ceiledPovY = Math.ceil(_worldMap.height / 2);
            } else {
                _ceiledPovX = Math.ceil(viewPointX);
                _ceiledPovY = Math.ceil(viewPointY);
            }
            
            // call all octants
            inspectNorthwestNorth(0, 1, 0);
            inspectNorthwestWest(0, 1, 0);
            inspectSouthwestWest(0, 1, 0);
            inspectSouthwestSouth(0, 1, 0);
            inspectSoutheastSouth(0, 1, 0);
            inspectSoutheastEast(0, 1, 0);
            inspectNortheastEast(0, 1, 0);
            inspectNortheastNorth(0, 1, 0);
            return _fovData;
        }
        
        public function clearFOV( ):void {
            _fovData.fillRect(new Rectangle(0,0,_worldMap.width, _worldMap.height), 0x000000);
        }
        // private methods
        // *******************************************************************************
        
        private function inspectNorthwestNorth(depth:int, startSlope:Number, endSlope:Number):void {
            var startX:int = _ceiledPovX - Math.ceil(startSlope * depth);
            var endX:int = _ceiledPovX - Math.ceil(endSlope * depth);
            var currentY:int = _ceiledPovY - depth;
            
            if (currentY < 0) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(startX, currentY) < _blockedColor;
            for (var currentX:int = Math.max(startX, 0); currentX <= endX; ++currentX) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = computeSlope(_ceiledPovX, _ceiledPovY, (currentX - 0.5), (currentY + 0.5));
                        // start recursion for the next depth
                        inspectNorthwestNorth(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = computeSlope(_ceiledPovX, _ceiledPovY, (currentX + 0.5), (currentY - 0.5));
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectNorthwestNorth(depth, startSlope, endSlope);
            }
        }
            
        private function inspectSouthwestWest(depth:int, startSlope:Number, endSlope:Number):void {
            var startY:int = Math.ceil(startSlope * depth) + _ceiledPovY;
            var endY:int = Math.ceil(endSlope * depth) + _ceiledPovY;
            var currentX:int = _ceiledPovX - depth;
            
            if (currentX < 0) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(currentX, startY) < _blockedColor;
            for (var currentY:int = Math.min(startY, _worldMap.height); currentY >= endY; --currentY) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = -computeInverseSlope((currentX + 0.5), (currentY + 0.5), _ceiledPovX, _ceiledPovY);
                        inspectSouthwestWest(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = -computeInverseSlope((currentX - 0.5), (currentY - 0.5), _ceiledPovX, _ceiledPovY);
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectSouthwestWest(depth, startSlope, endSlope);
            }
        }
        
        private function inspectNorthwestWest(depth:int, startSlope:Number, endSlope:Number):void {
            var startY:int = _ceiledPovY - Math.ceil(startSlope * depth);
            var endY:int = _ceiledPovY - Math.ceil(endSlope * depth);
            var currentX:int = _ceiledPovX - depth;
            
            if (currentX < 0) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(currentX, startY) < _blockedColor;
            for (var currentY:int = Math.max(startY, 0); currentY <= endY; ++currentY) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = computeInverseSlope((currentX + 0.5), (currentY - 0.5), _ceiledPovX, _ceiledPovY);
                        inspectNorthwestWest(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = computeInverseSlope((currentX - 0.5), (currentY + 0.5), _ceiledPovX, _ceiledPovY);
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectNorthwestWest(depth, startSlope, endSlope);
            }
        }
            
        private function inspectSouthwestSouth(depth:int, startSlope:Number, endSlope:Number):void {
            var startX:int = _ceiledPovX - Math.ceil(startSlope * depth);
            var endX:int = _ceiledPovX - Math.ceil(endSlope * depth);
            var currentY:int = _ceiledPovY + depth;
            
            if (currentY > _worldMap.height) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(startX, currentY) < _blockedColor;
            for (var currentX:int = Math.max(startX, 0); currentX <= endX; ++currentX) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = -computeSlope(_ceiledPovX, _ceiledPovY, (currentX - 0.5), (currentY - 0.5));
                        inspectSouthwestSouth(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = -computeSlope(_ceiledPovX, _ceiledPovY, (currentX + 0.5), (currentY + 0.5));
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectSouthwestSouth(depth, startSlope, endSlope);
            }
        }
        
        private function inspectSoutheastSouth(depth:int, startSlope:Number, endSlope:Number):void {
            var startX:int = Math.ceil(startSlope * depth) + _ceiledPovX;
            var endX:int = Math.ceil(endSlope * depth) + _ceiledPovX;
            var currentY:int = _ceiledPovY + depth;
            
            if (currentY > _worldMap.height) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(startX, currentY) < _blockedColor;
            for (var currentX:int = Math.min(startX, _worldMap.width); currentX >= endX; --currentX) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = computeSlope(_ceiledPovX, _ceiledPovY, (currentX + 0.5), (currentY - 0.5));
                        inspectSoutheastSouth(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = computeSlope(_ceiledPovX, _ceiledPovY, (currentX - 0.5), (currentY + 0.5));
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectSoutheastSouth(depth, startSlope, endSlope);
            }
        }
        
        private function inspectSoutheastEast(depth:int, startSlope:Number, endSlope:Number):void {
            var startY:int = _ceiledPovY + Math.ceil(startSlope * depth);
            var endY:int = _ceiledPovY + Math.ceil(endSlope * depth);
            var currentX:int = _ceiledPovX + depth;
            
            if (currentX > _worldMap.width) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(currentX, startY) < _blockedColor;
            for (var currentY:int = Math.min(startY, _worldMap.height); currentY >= endY; --currentY) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = computeInverseSlope((currentX - 0.5), (currentY + 0.5), _ceiledPovX, _ceiledPovY);
                        inspectSoutheastEast(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = computeInverseSlope((currentX + 0.5), (currentY - 0.5), _ceiledPovX, _ceiledPovY);
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectSoutheastEast(depth, startSlope, endSlope);
            }
        }
            
        private function inspectNortheastEast(depth:int, startSlope:Number, endSlope:Number):void {
            var startY:int = _ceiledPovY - Math.ceil(startSlope * depth);
            var endY:int = _ceiledPovY - Math.ceil(endSlope * depth);
            var currentX:int = _ceiledPovX + depth;
            
            if (currentX > _worldMap.width) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(currentX, startY) < _blockedColor;
            for (var currentY:int = Math.max(startY, 0); currentY <= endY; ++currentY) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = -computeInverseSlope((currentX - 0.5), (currentY - 0.5), _ceiledPovX, _ceiledPovY);
                        inspectNortheastEast(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = -computeInverseSlope((currentX + 0.5), (currentY + 0.5), _ceiledPovX, _ceiledPovY);
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectNortheastEast(depth, startSlope, endSlope);
            }
        }
                
        private function inspectNortheastNorth(depth:int, startSlope:Number, endSlope:Number):void {
            var startX:int = _ceiledPovX + Math.ceil(startSlope * depth);
            var endX:int = _ceiledPovX + Math.ceil(endSlope * depth);
            var currentY:int = _ceiledPovY - depth;
            
            if (currentY < 0) return;
            
            var isLastCellBlocked:Boolean = _worldMap.getPixel(startX, currentY) < _blockedColor;
            for (var currentX:int = Math.min(startX, _worldMap.width); currentX >= endX; --currentX) {
                if (_worldMap.getPixel(currentX, currentY) < _blockedColor) {
                    if (!isLastCellBlocked) {
                        var newScanEndSlope:Number = -computeSlope(_ceiledPovX, _ceiledPovY, (currentX + 0.5), (currentY + 0.5));
                        inspectNortheastNorth(depth + 1, startSlope, newScanEndSlope);
                    }
                    isLastCellBlocked = true;
                } else {
                    if (isLastCellBlocked) {
                        startSlope = -computeSlope(_ceiledPovX, _ceiledPovY, (currentX - 0.5), (currentY - 0.5));
                    }
                    _fovData.setPixel(currentX, currentY, _visibleColor);
                    isLastCellBlocked = false;
                }
            }
            if (!isLastCellBlocked) {
                depth++;
                inspectNortheastNorth(depth, startSlope, endSlope);
            }
        }
        
        private function computeSlope(x1:Number, y1:Number, x2:Number, y2:Number):Number {
            return ((x1 - x2) / (y1 - y2));
        }
        
        private function computeInverseSlope(x1:Number, y1:Number, x2:Number, y2:Number):Number {
            return (1 / ((x1 - x2) / (y1 - y2)));
        }

    }
}