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

ESCAPE FROM DARKNESS (fixed)

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

// forked from Albert's  ShadowCast: ESCAPE FROM DARKNESS (Growing darkness)
// forked from Albert's ShadowCast: ESCAPE FROM DARKNESS
// forked from Albert's forked from: forked from: forked from: forked from: forked from: ShadowCast
// forked from Albert's forked from: forked from: forked from: forked from: ShadowCast
// forked from Albert's forked from: forked from: forked from: ShadowCast
// forked from Albert's forked from: forked from: ShadowCast
// forked from Albert's forked from: ShadowCast
// forked from Albert's ShadowCast
// to load an image used this: http://wonderfl.net/c/d8DH/
// default image used from this: 
//using code from here: http://nemonon.de/blog/

//there are a lot of function need to be cleaned up...

package {
    import flash.geom.ColorTransform;
    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;
    import flash.text.*;
    
    
    import flash.utils.*;
    import com.bit101.components.*;    
    public class FlashTest extends Sprite {
        private var loader:Loader = new Loader(  );
        private var bd: BitmapData;
        private var bm2:Bitmap;
        private var loader2:Loader;
        private var labeldimension:Label;
        
        
        private const SIZE:int = 400;
        
        private var loaderA:Loader;
        private var loaderB:Loader;
        
        private var input:InputText;
        private var bitmap:Bitmap;        
        public function FlashTest() {
            init();
        }

        private static const URL:String = "http://dl.dropbox.com/u/292449/img/barlang_mockup.png"
//        private static const URL:String = "http://www.ujakropolisz.hu/files/ua_images/STATIKUS/Kultura/CIK_labirintus_m_3.jpg"
            private function init():void 
        {
            var label:Label = new Label(this, 50, 10, "loading " + URL);
            label = new Label(this, 25, 409, "IMAGE URL");
            input = new InputText(this, 0, 410, URL);
            input.width = 300;
            input.x = (465 - input.width) / 2;
            var button:PushButton = new PushButton(this, 230, 435, "OK", inputHandler);
            button.x = (465 - button.width) / 2;
            inputHandler();            
        }
        
        private function onClick(e:Event):void
        {
            //clearFOV();
            ColorTransformFOV();
            getFOV(stage.mouseX, stage.mouseY);
        }
            
        private function createTextField(x:Number, y:Number, width:Number, height:Number):TextField {
            var result:TextField = new TextField();
            result.x = x; result.y = y;
            result.width = width; result.height = height;
            addChild(result);
            return result;
        }
                    
    /**
     * 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:MyBitmapData;
        // 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 = 0xFAFAFA;
        // the color in the output data for the invisible pixels
        private var _invisibleColor:int = 0xFFFFFF;
        // the threshold color for the scan, pixel colors beneath this color will be invisible
        private var _blockedColor:uint = 0x000001;
        private var _colorTransform:ColorTransform = new ColorTransform(1,1,1,1,1,1,1,0);
        // 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():MyBitmapData {
            return _fovData;
        }
        
        
        /**
         * Sets the output data
         * @param newFovData
         */
        public function set fovData(newFovData:MyBitmapData):void {
            if (newFovData == null) {
                _fovData = new MyBitmapData(_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 MyBitmapData(_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), _invisibleColor);
        }
        
        public function ColorTransformFOV():void { 
            _fovData.colorTransform(new Rectangle(0,0,_fovData.width, _fovData.height), _colorTransform);
        }
        
        // private methods
        // *******************************************************************************
        
        private function inspectNorthwestNorth(depth:int, startSlope:Number, endSlope:Number):void {
            var startX:int = _ceiledPovX - Math.ceil(startSlope * depth) + 1;
            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) +1;
            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 - 1;
            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) + 1;
            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)));
        }



 

        
        
        private function inputHandler(event:Event = null):void
        {
            loaderA = new Loader();
            loaderA.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
            loaderA.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function():void { } );
            loaderA.load(new URLRequest(input.text), new LoaderContext(true));
        }
 
        private function initHandler(event:Event):void
        {    
            loaderB = new Loader();
            loaderB.contentLoaderInfo.addEventListener(Event.INIT, init2);
            loaderB.loadBytes(loaderA.contentLoaderInfo.bytes);
        }
        
        private function init2(event:Event):void
        {
            var loader:Loader = event.currentTarget.loader;
            
            var scale:Number = 0;
            if (loader.width < loader.height) scale = SIZE / loader.height;
            else scale = SIZE / loader.width;
            
            var bd:BitmapData = new BitmapData(scale * loader.width, scale * loader.height, false);
            bd.draw(loader);
            
            if (bitmap) removeChild(bitmap);
            bitmap = new Bitmap(bd);
            this.addChild(bitmap);

            var label:Label = new Label(this, 100, 2, ""+bitmap.width+"x"+bitmap.height);

            ShadowCaster(bd, true);
            var bmd2:BitmapData;
            fovData=null;
            bmd2=fovData;
            //blockedColor = 0x5050c0;
            bm2 = new Bitmap(bmd2);
            this.addChild(bm2);
            bm2.alpha=1;
            //bm2.blendMode = flash.display.BlendMode.MULTIPLY;            
            bm2.blendMode = flash.display.BlendMode.MULTIPLY;
            getFOV(45,65);//
            stage.addEventListener(Event.ENTER_FRAME , onClick);
            
        }
        

    }
}
import flash.display.BitmapData;

class MyBitmapData extends BitmapData{
    public function MyBitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)
   {
       super(width, height, transparent, fillColor);
   }
   
   override public function setPixel(x:int, y:int, color:uint):void
  {
      var colorOld:uint = getPixel(x,y);
      if (colorOld - (0xFFFFFF-color) < 0)
          super.setPixel(x,y,0);
      else
          super.setPixel(x,y,colorOld-(0xFFFFFF-color));
  }
 
 
    
}