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

2D random dungeon with FOV

1. make random dungeon (with iteration and attenuation)
2. add fog of war and Field of view
3. add character move code (wasd or arrow keys)

I will add more things!
- monster, stat, minimap, stair, death, animation...
/**
 * Copyright greentec ( http://wonderfl.net/user/greentec )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7saV
 */

package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.filters.BitmapFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import com.bit101.components.PushButton;
    
    /**
     * ...
     * @author ypc
     */
    [SWF(width="465", height="465", backgroundColor="#292929")]
    public class Main extends Sprite 
    {
        
        
        public var tileBitmapData:BitmapData;
        //public var tileBitmap:Bitmap;
        
        public var mapBitmapData:BitmapData;
        public var mapBitmap:Bitmap;
        
        public var mapArray:Array = [];
        public var mapWidth:int = 32;
        public var mapHeight:int = 32;
        
        
        //[Embed(source = "normal.png")]
        //public var tileImage:Class;
        
        //[Embed(source = "char1.png")]
        //public var tileImage:Class;
        //
        //public var colorMap:Object = { };
        //public var colorArray:Array = [];
        //public var colorBitmapIntegers:Array = [];
        
        public var tileColorArray:Array = [0x301800, 0x200000, 0xe07000, 0x804000, 0x603000, 0x402000, 0xa05000, 0xc06000, 0x101010, 0x505050, 0x606060, 0x404040, 0x303030, 0x202020];
        public var tileBitmapString:String = "011010100234445400101000023636440276226717643435056226731343633517636634133663340673434306343435023363400736343403336343033433450763343316633445176634441764443002667364063435450743453403334454127666330733445413346445173455450737344403434555066343540534545416334334010100101634434501101001043635450776767407643440056767670246434416336334063634011366333402734345036634341763454516366345076334541433334413365454076336450633444515463434076345441633444502445455143443451334454506363440035545550763343405445455036344000011001003445434010001110633440414767665136543550576767407343445023363440633434416636334174443400263645303343435073363440334340513363344066334441363444317344454023443430433434506343343036343450264343415343454067634451534450516634334055454540633434015554054076366440010100007664450001010000364334516737345063334011566773516334450063634341364454413636444023445050763444407634345163634431743545113633435166334441763463502334545063643340764345506363455025434540363334403434545036343450345455003636445063445450764340001101010023444540010100002363644114622671764343505622674134363351472763413366334037343430634343503236340073634340633634303343345037334331663344517663444176544300276736406343345154343340343545412666633076344441104644414345545073734440743343404514633011111111633433406464344167153440157677604363545034344450767111505734343024643441334345506363651176634340273434505434345176345331436634507643454101010111336444501155455043345111546343407635454147711110005510014344345153445450633763306700011076334341111110003334500076766001733643501577766063344041733437613663345057436340734344512663444163343441764643417444340073336330334343507336344033434051636363416634454166344451734445402636333053343450334335107634345026334341554345406764501163404051633436301010100063450661345405407636334067676630345664405440500026436451763734500563454000000051733444007363435137445441367776407344335076345440763434516363443174343411363345516633444176346350233344506364334076434550636345507543454036333450343454503634345034545400363644506344545076434000110101002344454001010010236364400462267176434350562245013436335147266341336633406734665111154550423634007363434033363640675111100433433166334451766343617376651005443640634354507434534063344331275543307335454133464431734554507373554054545550673435405345454163343351100001017344345011010010436354500100763076434400567676302464344100373340636340113663334027343450066343417634545163663450763345414333344133654540763364506364444154634340063454416334445024454441434434510044545013634400355454505633434000004550513450000110110554444340100011106555334147651551115435505767674073734450237400505665344166363341744434002636701033434350733634403343405133633605663344413634443173444540234434654334345063433430363434502643437153434540676344515344505167743343554545407334340155540540763774400101000076644500010100000643635107373450633340110007735100343400636343413644063100364440670540507634444046450351036344317470001136334351500064417634635023377450636433400663455063634550254345403633344034345450363434503454550036364450634454507643400011010100234445400101000023636440374446717643435056226731343633517646634133663340673434301043435033363400736343403336343005533450464343316633445176634441110553003467364053435450743453501111054147666331555545413346451111555050737344411114555066343511511115016334334010100101534434501101001043635450546551511513441115577450446434414336351073534011577633402734345054334351763154516446345076734541433434115765151063344450673444515453435007345401434444502445450143543451534400016463450035545150463443500511011043335000011011005445534011001110443400514767015146543550505577507345055023367010633435410577335174501500263675004343435005363400351510513363375056434541503445511011554023443630053434505743340105151410264343615043454157634551111451116734336015554551633454011551011076366440010100017665450001011100364334511557345063434011114773516334450057734341554454411636544043445050563444407354345143634531111115117733435167750341763463507265115073643340764650006363455025466410363334403433675036343450745455003636445063444400764340088888888888888888888888888888888889aa9bac8c9ab9bddc9baa9bd899aac8abcdddbd8bdcdbcd8adcdddd8addcd889cbdbbdd89dccbd89cd9bccd8ad9bdd8adbccdcd8b8dbdd89bbb9bcd8cbccbd89ccddcd8d8dd8889c9dcdbb88ddd9dc8acdd888d899cdd8bdcbdbbd8d8dcbbc8bdd88d89bccdd8d8ddc9cd8d8d8ddcd89888d88cdbdcdd88d8ddcd88d8d8ddd8b8bbd888dbcdbcd88bbc88dbcd8dd8d88b9cdb9c89c9ddc8bccdd8bc9cdd8888dcdc89cdc8bcbdd8dddcd8bddbcdcd88c9bc8bddc8bcbcd8dcccd8cdc9dbbdd8add8dddcbd8ddd8dccdd8d88dcbcdbd8acbd8cdd9cd8ccd88d8888d8db9bbcd89cd8ddbbcdd8cdd8d88b9d888dcccdc8add8d8dcbc88dd88889cdcd888dddcd88d8888dcdd8bc88cd8bdbddd8888dcd8d8dbbd8dd8bccddddc8cbcdc8cdd88d8abcd9dd888bcdcbbdd8dcdcd8dcbd888a9d9bd89bd8d8bdcdd88dcd89db9d8889bdccd9dc98d8cddd8bd8888bc9bbd88888888bcdb99d88889ccd8888dbbdd88a8cc8bcdbddc9b889dcbd89cd8dd8888b9bd8bcd99ccc888bdbdd89ddc88ddd89ddb88dccbcd8bdd8ddd89d9bbdddcd8ac888d8dcdb89cbd8d88bccbddddbdc88899d888dc889dccd8888ddcdb9dbdb8ccbdbc8d8889cbcdd8b998dddbccddc8a9ddbc888dbdbbddc89cbb88dddbbcc8abdccdd8d8bcdccdd89dcdd8dddddcc8bdccccdd88ddcddcd8cdddd88888ddd88888888888888888888888888888888888ba9bac8c9ab9bddc9baa9b9b9d8d888baccdbd8bdcdbcdcadcddbcbdc9dd889ac9cbdd89dccbd8dda9bccbdcd9b9d8a9bbcdcd8b8dbdd88ddb9bcbcdbccbd89cbcdbd8d8dd888dd8ddacbcbddd9dc8ab9cb88d899bc9cbdc88dbdddcdcbbc8bcbcdd89bccddd9dcb888d8dcd8ddcd89bcdcd8cdbdcbcbcbcdd88888888ddd8bcbccd88dbcdbdbcccbcc8dbcd8dd8d888dddb9c89b9cbdcbccdd8bc9cdd8888d88889cdc89cbddbcdddc8bddbcdcd88c9b88bddc8bcbccddcccd8cdc9dbbdd8add8dddcbd8ddd8dccdd8d88dcbcdbd8acbd8cdd9cd8ccd88d8888d8db9bbcd89cd8ddbbcdd88888d88b9d8d8dcccdc8add8d8dcb888dd88889cdcd888dddcd88d8888dc888bbc8dd8bdbddd8d88dcd8d8dbbd888bbccccddc8cbcdc8cdd88d8abcd9dd899ccdcdcdd8dcdcd8dcbd888a9d9bd89cdddcddcdd88dcd89db9d8889bdccd9cccdcddcdd8bd8888bc9bbd88888888bcdcdcdcd889ccd8888dbbdd88a8cc8bcdbddcdd889dcbd89cd8dd8888b9bd8bcd99ccc888bdbdd89ddc88d8d89ddb88dccbcd8bdd8ddd89d9bbd888d8ac888d8dcdb89cbd8d88bccbdd889dc88899d888dc889dccd8888ddcd8c9bdb8ccbdbc8d8889cbcdd8b998ddd89bcdc8a9ddbc888dbdbbddc89cbb888d9bbcc8abdccdd8d8bcdccdd89dcdd8d9bcccc8bdccccdd88ddcddcd8cdddd88bc8ddd88888888888888888888888888888888889aa98cd8b9ab9bddc9baa9bd899aac8abccdd8c9cdcdbcd8adcdddd89bbcd889ccdbbd89cdccbd89cd9bccd8ab9bdd8adbccdcd8b8dbdd89bbb9bcd8abccbd8dbcddcd8d8dd8889c9dcdbb8abcb9dc88dbb888d9bbcdd8bdcbdbbdcaccbbbc8dc888d89cbcdd8d8ddc9cd8abdccbcd888d8d88bdcdcdd88d8ddcd8accdccbd8dcbbd888dbcdbcd88bbc88acbbbdcbd8bb9bbb9b8889ddc8bcbdd8accccddd889cdcb9ccbbb88dd8bddcd8bcbbcccb88a9bdcbcbcdcc8cd8dcccd8cdc9dcddd89ddddcbddddcd88dccdd8d88d9ccdcd8bccddcccddddc8888d8888d8dcbdccd8bcddddcdccddcd88d8bb9d888dcccdc8adddcddccdddcd8888ccccd888ddddd8bdddcdcdcdcdd88cd8bbcbdd8888dcd8c9ccdbcddccdcd8ddbbddcdbdcdd88d88bdcddbcdcdddc8bdcddcdcddbcbd888889dccbcbcdcd8bcdddccccddbd9d888c98cddcccdcd88bccdbdcdbccdddbd889b98ddccdd88888cbdbdbdccdbbddd889ccc8ddd88d99b8bcccddccbcdddd888bccd8bc889cddd8bddccdcbccdcdddd89ddb88889bcccb8dcdcbbdccddcddcd8ac888d8d9dcddc8dcbccdddcdcddbdc88899d88cccdccd88dcddccbdcccdbdb8ccbdbc8ddcc9cbc8dcb99dcddcdcddc8a9ddbc88ddcdbbdd8cccbcccdddbbcc8abdccdd8d8bcdccd88cdccdccddddcc8bdccccdd88ddcddcd8cdddd88888ddd88888888888888888888888888888888889aa88abbc9ab9b88c9baa9bd899aac8abcd8bbddddcdbc88adcdddd8addcd889cbd8bddcccdcdc89cd9bccd8ad9bdd8adbc8dcddcdddcd89bbb9bc88cbccbd89ccd8cd8dcdcccd9c9dcdb888ddd9dc8acddd88dcdcddc8bdcbd8888d8dcbbc8bdd8dd88dccdcdd888d98d8d8d8ddcd89ddd888d8ddccd8ddd8d8d88d8d8ddd8bd8d8d88dbccd8d8cddd88dbcd8dd8d888d88b9c89dd8ddc9c88d8bc9cdd8888dc8d89c8c8b888c9cdd88ddddbcdcd88c9bc8b8dcdc8cc9cdbcd88ddc9dbbdd8adddd888dc8cdcdcdbcc88d8888cdbd8acbd888888c8dd8ddcbbcc8ddd8bbcd89cd8ddcbc8dd88d8dccbcd88d8cccdc8add8dcdcb8c8dc888ddcbdd8d8dddcd88d888ccc88bd99cddcdcdd8dd888dcd8d8dc8d8cb9bbcbdd8dcdd88c8cdd88d8acccc888bc9cccdc8d8888d8ddcbd888a9bcb888bcbccdddd8dbcdcdddb9d8889cdcc898dbbcdcc88dbdcd8d889bbd888cddd88cddcdcddd8ccddd8888bbdd88acdb8b888d8d8dd8dd88dd9cd88d8888b9bd8bc888d8d888888d889ddc88ddd89ddb88dc88888bd88d8d89d9bbdddcd8ac888d8d8db89cbd8d8dbccbddddbdc88899d888dc889dccd8888ddcdb9dbdb8ccbdbc8d8889cbcdd8b998dddbccddc8a9ddbc888dbdbbddc89cbb88dddbbcc8abdccdd8d8bcdccdd89dcdd8dddddcc8bdccccdd88ddcddcd8cdddd88888ddd";
        
        public var charColorArray:Array = [0x0, 0xff774e39, 0xff291f14, 0xff282038, 0xffd48c52, 0xff000000, 0xff452e30, 0xffa397db, 0xffebb385, 0xffc9ccf8, 0xffa17854, 0xfffcd9af, 0xff806cb3, 0xffc1ab84, 0xff838670, 0xff506ba5];
        public var charBitmapString:String = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000000200022000000031445500000000000006202622220003718163500000000200212661622000379a863b850000000622612616228220699a134b850000002126116116662222777ca31445000000616a16a16166611622c63551550000006a1d1a16116228841ccccc3ccc3650021daaa111162e99b8437797cc773ee6561aa1666662155ffb8179997c793bde161a161aa162155ffbb4c9999c793bdea611611ada162888bbb41ad11311ddee166111aa66222288bbb81199c3ce6ee65266166622bbb888bbb81aad13ed6550026662222bbbb888bbb81199c3ce6ee65661a26222bbb888bbb41ad11311ddee161aa61aa622155ffbb4c9999c793bdea61da161da16255ffb8179997c793bde121a1a166111629b98417797cc773ee652616d1662661628841ccccc3ccc3650002161a1662226611622c63551550000002626111666622222777ca314450000000202611166228220699a134b850000000000216266222000379a863b850000000000262026222200037181f3500000000000020002200000003144550000000000000000002000000000110000000000000000000000000000000000000000000000000000000000000000000000000";
        
        public var roomMinWidth:int = 6;
        public var roomMaxWidth:int = 10;
        public var directionSelectMax:int = 4;
        public var directionSelectProb:int = 90;
        public var attenuationMin:int = 70; //make room smaller
        public var attenuationMax:int = 90;
        public var attenuationNumMax:int = 4;
        public var corridorMin:int = 1;
        public var corridorMax:int = 4;
        
        public var startPointX:int;
        public var startPointY:int;
        public var cameraPointX:int;
        public var cameraPointY:int;
        
        public var char:Character;
        
        public var fogBitmapData:BitmapData;
        public var fogBitmap:Bitmap;
        public var fogArray:Array = [];
        public var lightSourceDistance:int = 7;
        
        public var noiseBitmapData:BitmapData;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            stage.scaleMode = "noScale";
            
            tileBitmapData = new BitmapData(32 * 8, 32, true, 0x0);
            
            //initialize tile graphics with color compressed string
            var i:int, j:int;
            var index:int;
            
            for (i = 0; i < 256; i += 1)
            {
                for (j = 0; j < 32; j += 1)
                {
                    index = parseInt("0x" + tileBitmapString.substr(i * 32 + j, 1));
                    tileBitmapData.setPixel32(i, j, 0xff << 24 | tileColorArray[index]);
                }
            }
            
            
            //initialize map array
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    mapArray.push(-1);
                }
            }
            
            
            //make random dungeon
            var roomW:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
            var roomH:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
            var roomX:int = int(mapWidth / 2 - roomW / 2);
            var roomY:int = int(mapHeight / 2 - roomH / 2);
            makeRoom(roomX, roomY, roomW, roomH, 1);
            
            
            //make edge wall for natural map - south, east
            for (i = 0; i < mapWidth; i += 1)
            {
                mapArray[i * mapHeight + mapWidth - 1] = 1; //south
            }
            for (i = 0; i < mapHeight; i += 1)
            {
                mapArray[(mapWidth - 1) * mapHeight + i] = 1; //east
            }
            
            
            //draw tile to map
            mapBitmapData = new BitmapData(32 * mapWidth, 32 * mapHeight, false, 0x0);
            
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    index = Math.random() * 4;
                    
                    if (mapArray[i * mapHeight + j] == 0) //floor
                    {
                        index += 4;
                    }
                    
                    //draw tile
                    mapBitmapData.copyPixels(tileBitmapData, new Rectangle(32 * index, 0, 32, 32), new Point(i * 32, j * 32));
                    
                }
            }
            
            //set camera and starting point
            mapBitmap = new Bitmap(mapBitmapData);
            
            startPointX = int(Math.random() * roomW) + roomX;
            startPointY = int(Math.random() * roomH) + roomY;
            cameraPointX = startPointX - 7;
            cameraPointY = startPointY - 7;
            mapBitmap.x = -1 * 32 * cameraPointX;
            mapBitmap.y = -1 * 32 * cameraPointY;
            
            addChild(mapBitmap);
            
            
            //initialize character
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x0);
            for (i = 0; i < 32; i += 1)
            {
                for (j = 0; j < 32; j += 1)
                {
                    index = parseInt("0x" + charBitmapString.substr(i * 32 + j, 1));
                    if (index != 0)
                    {
                        bitmapData.setPixel32(i, j, charColorArray[index]);
                    }
                }
            }
            
            char = new Character(startPointX, startPointY, new Bitmap(bitmapData));
            char.x = 32 * 7;
            char.y = 32 * 7;
            addChild(char);
            
            
            //character move listener
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            
            
            
            //initialize fog
            fogBitmapData = new BitmapData(32 * mapWidth, 32 * mapHeight, true, 0xff000000);
            fogBitmap = new Bitmap(fogBitmapData);
            
            fogBitmap.x = mapBitmap.x;
            fogBitmap.y = mapBitmap.y;
            addChild(fogBitmap);
            
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    fogArray.push( -1);
                }
            }
            
            //initialize fog noise
            noiseBitmapData = new BitmapData(32, 32, true, 0);
            noiseBitmapData.noise(int.MAX_VALUE * Math.random(), 0, 50, 7, true);
            noiseBitmapData.colorTransform(noiseBitmapData.rect, new ColorTransform(1, 1, 1, 0.1, 0, 0, 0, 0));
            //noiseBitmapData.noise(int.MAX_VALUE * Math.random(), 0, 255, 7);
            
            
            drawFog();
            
            
            var button:PushButton = new PushButton(this, 465 - 110, 465 - 30, "Reset", onReset);
            
            //tileBitmapData.fillRect(new Rectangle(0, 0, 32, 32), 0xffff0000);
            
            //graphic compress code!!
            /*
            var bmp:Bitmap = new tileImage();
            var bitmapData:BitmapData = bmp.bitmapData;
            var _width:int = bitmapData.width;
            var _height:int = bitmapData.height;
            var color:uint;
            
            for (i = 0; i < _width; i += 1)
            {
                for (j = 0; j < _height; j += 1)
                {
                    color = bitmapData.getPixel32(i, j);
                    
                    if (colorMap.hasOwnProperty(color) == false)
                    {
                        colorMap[color] = 1;
                       colorArray.push(color);
                    }
                    
                    colorBitmapIntegers.push(colorArray.indexOf(color).toString(16));
                }
            }
            
            trace(colorArray.length);
            
            var str:String = "";
            for (i = 0; i < colorArray.length; i += 1)
            {
                str += "0x" + colorArray[i].toString(16) + ",";
            }
            trace(str);
            trace("");
            
            trace(colorBitmapIntegers.join(""));
            */
            
            
        }
        
        private function onReset(e:Event):void
        {
            var i:int, j:int;
            var index:int;
            
            //reset map array
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    mapArray[i * mapHeight + j] = -1;
                }
            }
            
            //make random dungeon
            var roomW:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
            var roomH:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
            var roomX:int = int(mapWidth / 2 - roomW / 2);
            var roomY:int = int(mapHeight / 2 - roomH / 2);
            makeRoom(roomX, roomY, roomW, roomH, 1);
            
            
            //make edge wall for natural map - south, east
            for (i = 0; i < mapWidth; i += 1)
            {
                mapArray[i * mapHeight + mapWidth - 1] = 1; //south
            }
            for (i = 0; i < mapHeight; i += 1)
            {
                mapArray[(mapWidth - 1) * mapHeight + i] = 1; //east
            }
            
            
            //draw tile to map
            mapBitmapData.fillRect(mapBitmapData.rect, 0x0);
            
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    index = Math.random() * 4;
                    
                    if (mapArray[i * mapHeight + j] == 0) //floor
                    {
                        index += 4;
                    }
                    
                    //draw tile
                    mapBitmapData.copyPixels(tileBitmapData, new Rectangle(32 * index, 0, 32, 32), new Point(i * 32, j * 32));
                    
                }
            }
            
            //set camera and starting point
            startPointX = int(Math.random() * roomW) + roomX;
            startPointY = int(Math.random() * roomH) + roomY;
            cameraPointX = startPointX - 7;
            cameraPointY = startPointY - 7;
            mapBitmap.x = -1 * 32 * cameraPointX;
            mapBitmap.y = -1 * 32 * cameraPointY;
            
            
            //reset character
            char.posX = startPointX;
            char.posY = startPointY;
            char.x = 32 * 7;
            char.y = 32 * 7;
            
            
            //reset fog
            fogBitmapData.fillRect(fogBitmapData.rect, 0xff000000);            
            
            fogBitmap.x = mapBitmap.x;
            fogBitmap.y = mapBitmap.y;
            
            for (i = 0; i < mapWidth; i += 1)
            {
                for (j = 0; j < mapHeight; j += 1)
                {
                    fogArray[i * mapHeight + j] = -1;
                }
            }
            
            drawFog();
            
            
        }
        
        private function drawFog():void
        {
            var i:int, j:int;
            var maxScreenX:int = Math.min(cameraPointX + 15, mapWidth);
            var maxScreenY:int = Math.min(cameraPointY + 15, mapHeight);
            var dist:int;
            
            
            //judge line of sight
            var lineSightArray:Array = [];
            for (i = cameraPointX; i < maxScreenX; i += 1)
            {
                for (j = cameraPointY; j < maxScreenY; j += 1)
                {
                    lineSightArray.push( -1);
                }
            }
            
            lineSightArray[(char.posX - cameraPointX) * 15 + (char.posY - cameraPointY)] = 0;
            
            var dx:Number;
            var dy:Number;
            var nowX:Number;
            var nowY:Number;
            
            for (i = -180; i <= 180; i += 1)
            {
                dx = Math.cos(Number(i) * 0.01744);
                dy = Math.sin(Number(i) * 0.01744);
                
                nowX = char.posX + dx + 0.5;
                nowY = char.posY + dy + 0.5;
                
                for (j = 0; j < 7; j += 1)
                {
                    lineSightArray[int(nowX - cameraPointX) * 15 + int(nowY - cameraPointY)] = 0;
                    
                    if (mapArray[int(nowX) * mapHeight + int(nowY)] != 0)
                    {
                        break;
                    }
                    
                    nowX += dx;
                    nowY += dy;
                    
                }
                
                
            }
            
            //initialize fogAlpha : visited -> 0
            for (i = cameraPointX; i < maxScreenX; i += 1)
            {
                for (j = cameraPointY; j < maxScreenY; j += 1)
                {
                    if (fogArray[i * mapHeight + j] > 0)
                    {
                        fogArray[i * mapHeight + j] = 0;
                    }
                }
            }
            
            
            //calculate distance from char (light source)
            for (i = cameraPointX; i < maxScreenX; i += 1)
            {
                for (j = cameraPointY; j < maxScreenY; j += 1)
                {
                    dist = Math.abs(char.posX - i) + Math.abs(char.posY - j);
                    if (dist <= lightSourceDistance)
                    {
                        if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == 0) //can see
                        {
                            fogArray[i * mapHeight + j] = lightSourceDistance - dist;
                        }
                        else
                        {
                            //fogArray[i * mapHeight + j] = 0;
                        }
                        
                        
                    }
                }
            }
            
            
            //trace((char.posX - cameraPointX), (char.posY - cameraPointY));
            
            //draw fog
            fogBitmapData.fillRect(new Rectangle(cameraPointX * 32, cameraPointY * 32, (maxScreenX - cameraPointX) * 32, (maxScreenY - cameraPointY) * 32), 0x00ffffff);
            var fogRect:Rectangle;
            var fogAlpha:int;
            var color:uint;
            
            for (i = cameraPointX; i < maxScreenX; i += 1)
            {
                for (j = cameraPointY; j < maxScreenY; j += 1)
                {
                    fogRect = new Rectangle(i * 32, j * 32, 32, 32);
                    fogAlpha = fogArray[i * mapHeight + j];
                    //trace((i - cameraPointX), (j - cameraPointY));
                    //trace(lineSightArray[(i - cameraPointX) * mapHeight + (j - cameraPointY)]);
                    
                    if (fogAlpha == -1) //unvisited
                    {
                        fogBitmapData.fillRect(fogRect, 0xff000000);
                    }
                    else if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == -1) //can't see, but visited
                    {
                        color = ((lightSourceDistance - 0) / (lightSourceDistance + 1) * 255) << 24; //+1 for visited place
                        fogBitmapData.fillRect(fogRect, color);
                        
                        //add noise
                        fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "lighten");
                        
                    }
                    else
                    {
                        if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == 0) //can see, visited
                        {
                            
                            color = ((lightSourceDistance - fogAlpha) / (lightSourceDistance + 1) * 255) << 24; //+1 for visited place
                            fogBitmapData.fillRect(fogRect, color);
                            
                            //add noise
                            //fogBitmapData.applyFilter(noiseBitmapData, noiseBitmapData.rect, new Point(i * 32, j * 32), new BitmapFilter());
                            fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "lighten");
                            //fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "multiply");
                        }
                        
                    }
                    
                }
            }
            
            /*
            for (i = 0; i < 15; i += 1)
            {
                var str:String = "";
                
                for (j = 0; j < 15; j += 1)
                {
                    str = str.concat(String(lineSightArray[i * 15 + j]) + "\t");
                }
                
                trace(str);
            }
            */
            
        }
        
        private function onKeyDown(e:KeyboardEvent):void
        {
            switch(e.keyCode)
            {
                case 87: //w
                case 38: //Up
                    //wall check
                    if (char.posY - 1 >= 0 && 
                        mapArray[char.posX * mapHeight + (char.posY - 1)] == 0)
                    {
                        charMove(0, -1);
                        drawFog();
                    }
                    
                    
                    
                    break;
                
                case 83: //s
                case 40: //Down
                    //wall check
                    if (char.posY + 1 < mapHeight &&
                        mapArray[char.posX * mapHeight + (char.posY + 1)] == 0)
                    {
                        charMove(0, 1);
                        drawFog();
                    }
                    
                    break;
                    
                case 65: //a
                case 37: //Left
                    //wall check
                    if (char.posX - 1 >= 0 && 
                        mapArray[(char.posX - 1) * mapHeight + char.posY] == 0)
                    {
                        charMove( -1, 0);
                        drawFog();
                    }
                    
                    break;
                    
                case 68: //d
                case 39: //Right
                    //wall check
                    if (char.posX + 1 < mapWidth && 
                        mapArray[(char.posX + 1) * mapHeight + char.posY] == 0)
                    {
                        charMove(1, 0);
                        drawFog();
                    }
                    
                    break;
                
                
            }
        }
        
        private function charMove(moveX:int, moveY:int):void
        {
            //trace(char.posX, char.posY, cameraPointX, cameraPointY);
            
            char.posX += moveX;
            char.posY += moveY;
            
            /*
            //edge move - don't scroll map
            if (cameraPointX == 0)
            {
                char.x += moveX * 32;
                char.y += moveY * 32;
                
                //mapBitmap.y -= moveY * 32;
                return;
            }
            if (cameraPointY == 0)
            {
                char.x += moveX * 32;
                char.y += moveY * 32;
                
                //mapBitmap.x -= moveX * 32;
                return;
            }
            */
            
            //map scroll
            if (char.posX - cameraPointX == 3 && cameraPointX != 0)
            {
                mapBitmap.x += 32;
                cameraPointX -= 1;
                fogBitmap.x = mapBitmap.x;
                
                return;
            }
            if (cameraPointX + 14 - char.posX == 3 && cameraPointX != mapWidth - 15)
            {
                mapBitmap.x -= 32;
                cameraPointX += 1;
                fogBitmap.x = mapBitmap.x;
                
                return;
            }
            if (char.posY - cameraPointY == 3 && cameraPointY != 0)
            {
                mapBitmap.y += 32;
                cameraPointY -= 1;
                fogBitmap.y = mapBitmap.y;
                
                return;
            }
            if (cameraPointY + 14 - char.posY == 3 && cameraPointY != mapHeight - 15)
            {
                mapBitmap.y -= 32;
                cameraPointY += 1;
                fogBitmap.y = mapBitmap.y;
                
                return;
            }
            
            char.x += moveX * 32;
            char.y += moveY * 32;
            
            
        }
        
        
        private function makeRoom(roomX:int, roomY:int, roomWidth:int, roomHeight:int, scaleFactor:int):void
        {
            //trace("roomX: ", roomX, "\nroomY:", roomY, "\nroomWidth:", roomWidth, "\nroomHeight:", roomHeight);
            var i:int, j:int;
            
            //check possible
            if (roomX < 0 || roomX >= mapWidth || roomY < 0 || roomY >= mapHeight)
            {
                //trace("fail to batch");
                return;
            }
            if (roomX + roomWidth >= mapWidth || roomY + roomHeight >= mapHeight)
            {
                //trace("fail to batch room");
                return;
            }
            
            /*
            for (i = roomX; i < roomX + roomWidth; i += 1)
            {
                for (j = roomY; j < roomY + roomHeight; j += 1)
                {
                    if (mapArray[i * mapHeight + j] != -1)
                    {
                        //trace("not empty space");
                        return;
                    }
                }
            }
            */
            
            //make empty place
            for (i = roomX; i < roomX + roomWidth; i += 1)
            {
                for (j = roomY; j < roomY + roomHeight; j += 1)
                {
                    mapArray[i * mapHeight + j] = 0;
                }
            }
            
            if (scaleFactor == attenuationNumMax)
            {
                return;
            }
            
            //direction select
            var directionArray:Array = [0, 1, 2, 3];
            var directionIndex:int;
            var direction:int;
            
            var childRoomW:int;
            var childRoomH:int;
            var childRoomX:int;
            var childRoomY:int;
            
            var corridorIndex:int;
            var corridorLength:int;
            var corridorCellX:int;
            var corridorCellY:int;
            
            for (i = 0; i < directionSelectMax; i += 1)
            {
                if (Math.random() * 100 > directionSelectProb)
                {
                    continue;
                }
                
                childRoomW = roomWidth * (Math.random() * (attenuationMax - attenuationMin) + attenuationMin) / 100;
                childRoomH = roomHeight * (Math.random() * (attenuationMax - attenuationMin) + attenuationMin) / 100;
                
                directionIndex = int(Math.random() * directionArray.length);
                direction = directionArray.splice(directionIndex, 1);
                
                switch(direction)
                {
                    case 0: //N
                        
                        //roomW = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
                        childRoomX = int(Math.random() * (roomWidth - childRoomW)) + roomX;
                        corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
                        childRoomY = roomY - childRoomH - corridorLength;
                        
                        //make corridor
                        corridorIndex = int(Math.random() * childRoomW) + childRoomX;
                        for (j = 0; j < corridorLength; j += 1)
                        {
                            corridorCellX = corridorIndex;
                            corridorCellY = roomY - 1 - j;
                            
                            if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
                            {
                                break;
                            }
                            
                            mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
                            //trace("corridor:", corridorCellX, corridorCellY);
                        }
                        
                        break;
                        
                    case 1: //W
                        
                        corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
                        childRoomX = roomX - childRoomW - corridorLength;
                        childRoomY = int(Math.random() * (roomHeight - childRoomH)) + roomY;
                        
                        //make corridor
                        corridorIndex = int(Math.random() * childRoomH) + childRoomY;
                        for (j = 0; j < corridorLength; j += 1)
                        {
                            corridorCellX = roomX - 1 - j;
                            corridorCellY = corridorIndex;
                            
                            if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
                            {
                                break;
                            }
                            
                            mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
                            //trace("corridor:", corridorCellX, corridorCellY);
                        }
                        
                        break;
                        
                    case 2: //S
                        
                        childRoomX = int(Math.random() * (roomWidth - childRoomW)) + roomX;
                        corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
                        childRoomY = roomY + roomHeight + corridorLength;
                        
                        //make corridor
                        corridorIndex = int(Math.random() * childRoomW) + childRoomX;
                        for (j = 0; j < corridorLength; j += 1)
                        {
                            corridorCellX = corridorIndex;
                            corridorCellY = roomY + roomHeight + j;
                            
                            if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
                            {
                                break;
                            }
                            
                            mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
                            //trace("corridor:", corridorCellX, corridorCellY);
                        }
                        
                        break;
                        
                    case 3: //E
                        
                        corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
                        childRoomX = roomX + roomWidth + corridorLength;
                        childRoomY = int(Math.random() * (roomHeight - childRoomH)) + roomY;
                        
                        //make corridor
                        corridorIndex = int(Math.random() * childRoomH) + childRoomY;
                        for (j = 0; j < corridorLength; j += 1)
                        {
                            corridorCellX = roomX + roomWidth + j;
                            corridorCellY = corridorIndex;
                            
                            if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
                            {
                                break;
                            }
                            
                            mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
                            //trace("corridor:", corridorCellX, corridorCellY);
                        }
                        
                        break;
                }
                
                //trace("make to:", roomX, roomY, childRoomX, childRoomY);
                makeRoom(childRoomX, childRoomY, childRoomW, childRoomH, scaleFactor + 1);
                
                
            }
            
            
            
            
        }
        
    }
    

}
Class
{
    import flash.display.Bitmap;
    import flash.display.Sprite;
    /**
     * ...
     * @author ypc
     */
    class Character extends Sprite
    {
        public var posX:int;
        public var posY:int;
        public var bitmap:Bitmap;
        
        public function Character(_x:int, _y:int, bmp:Bitmap) 
        {
            posX = _x;
            posY = _y;
            bitmap = bmp;
            addChild(bitmap);
        }
        
    }

}