forked from: 不思議のダンジョン自動生成

by takimo forked from 不思議のダンジョン自動生成 (diff: 1)
♥0 | Line 197 | Modified 2009-12-31 10:12:50 | MIT License
play

ActionScript3 source code

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

// forked from takimo's 不思議のダンジョン自動生成
package {
	import flash.utils.IDataInput;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.geom.Rectangle;
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    
    //参考:http://d.hatena.ne.jp/Gemma/20070816
    
    public class RogueMap extends Sprite {
    		private var _debug:TextField;
    		private var _margin:uint = 8; 
    		private var _dungeonWidth:uint = 60;
    		private var _dungeonHeight:uint = 30;
    		private var _fontSize:uint = 12;
    		private var _rectArray:Array;
    		private var _dungeon:Array;
    		private var _format:TextFormat;
    		
        public function RogueMap() {
            startDebug();
            
            var rect:Rectangle = new Rectangle(0, 0, _dungeonWidth - 1, _dungeonHeight - 1);
            _dungeon = new Array(_dungeonHeight);
            for (var j:int=0; j<_dungeonHeight; j++)
            {
            		_dungeon[j] =new Array(_dungeonWidth);
            		for(var i:int=0; i < _dungeonWidth; i++)
            		{
            			_dungeon[j][i] =' ';
            		}
            }
            
            var compartments:Array = flatten(split(rect), []);
            debug(String(compartments.length));
            
            var rooms:Array = compartments.map(createRoom);
         	for each (var room:Rectangle in rooms)
			{
				//debug(String(item.toString()));
				drawRect(room);
			}

            createRoad(compartments, rooms);
			
            for each (var row:Array in _dungeon)
            {
            		for each (var column:String in row)
            		{
            			debug(column, false);
            		}
            		debug('\n', false);
            }
            
        }
        
        private function half(n:int):int
        {
        		return int(n >> 1);
        }

        private function fill(rect:Rectangle, parts:String ="#"):void
        {
        		//debug("top :" + String(rect.top) + ", bottom:" + String(rect.bottom) + ", left:" + String(rect.left) + ",right: " + String(rect.right));
			var min_j:int = Math.min(rect.top, rect.bottom);
			var max_j:int = Math.max(rect.top, rect.bottom);
			var min_i:int = Math.min(rect.left, rect.right);
			var max_i:int = Math.max(rect.left, rect.right);
  			
  			for (var j:int = min_j; j <= max_j; j++)
				for (var i:int = min_i; i <= max_i; i++)
					_dungeon[j][i] = parts;
		}
		
		private function drawRect(rect:Rectangle, parts:String ="|", parts1:String = "-"):void
		{
			var min_j:int = Math.min(rect.top, rect.bottom);
			var max_j:int = Math.max(rect.top, rect.bottom);
			var min_i:int = Math.min(rect.left, rect.right);
			var max_i:int = Math.max(rect.left, rect.right);
			
			for (var j:int = min_j; j <= max_j; j++)
			{
			    _dungeon[j][min_i - 1] = parts; 
				_dungeon[j][max_i + 1] = parts;
			}
			for (var i:int = min_i; i <= max_i; i++)
			{
     	 		_dungeon[min_j - 1][i] = parts1; 
    				_dungeon[max_j + 1][i] = parts1;
  			} 
		}     
        private function randomRange(min:int, max:int):int
        {
        		if(min > max) return 0;
        		else if(min == max) return min;
        		else return Math.floor(Math.random() * (max - min)) + min;	
        }
        
        private function createRoad(compartments:Array, rooms:Array):void
        {
        		var connectList:Array = new Array();
        		for (var i:int = 0; i < compartments.length - 1; i++)
        			connectList.push([i, i + 1]);
        		
		  	for (var k:int = 0; k < compartments.length; k++)
				for (var j:int = k + 1; j < compartments.length; j++)
					if (randomRange(0,5) == 0)
						if (compartments[k].left == compartments[j].right ||
							compartments[k].right == compartments[j].left ||
							compartments[k].top == compartments[j].bottom ||
							compartments[k].bottom == compartments[j].top)
								connectList.push([k,j]);
			
            for each (var connect:Array in connectList)
            {
            		var from:int = connect[0];
            		var to:int = connect[1];
            		//debug(String(from) + ":" + String(to));
            		var parentCompartment:Rectangle = compartments[from];
            		var childrenCompartment:Rectangle = compartments[to];
            		var parentRoom:Rectangle = rooms[from];
            		var childrenRoom:Rectangle = rooms[to];
            		
				if (parentCompartment.bottom == childrenCompartment.top)
				{
					// N
					var a:int = randomRange(parentRoom.left, parentRoom.right);
					var b:int = randomRange(childrenRoom.left, childrenRoom.right);
					//debug(String(a) + "," + String(b));
					/**
					fillRect(a, half(parentCompartment.top + parentCompartment.bottom), a, parentCompartment.bottom);
					fillRect(b, half(childrenCompartment.top + childrenCompartment.bottom), b, childrenCompartment.top);
					fillRect(a, parentCompartment.bottom, b, childrenCompartment.top);
					*/
					fillRect(a, parentRoom.bottom + 1, a, parentCompartment.bottom);
					fillRect(b, childrenRoom.top - 1, b, childrenCompartment.top);
					fillRect(a, parentCompartment.bottom, b, childrenCompartment.top);
				}
				else if (parentCompartment.right == childrenCompartment.left)
				{
					// Z
					a = randomRange(parentRoom.top + 1, parentRoom.bottom - 1);
					b = randomRange(childrenRoom.top + 1, childrenRoom.bottom - 1);
					//debug(String(a) + "," + String(b));
					fillRect(parentRoom.right + 1, a, parentCompartment.right, a);
					fillRect(childrenRoom.left - 1, b, childrenCompartment.left, b);
					fillRect(parentCompartment.right, a, childrenCompartment.left, b);
					/**
					fillRect(half(parentRoom.left + parentRoom.right), a, parentCompartment.right, a);
					fillRect(half(childrenRoom.left + childrenRoom.right), b, childrenCompartment.left, b);
					fillRect(parentCompartment.right, a, childrenCompartment.left, b);
					*/
				}
            }
            
        }
        
        private function fillRect(x0:int, y0:int, x1:int, y1:int):void
        {
        		var rect:Rectangle = new Rectangle();
        		rect.topLeft = new Point(Number(x0), Number(y0));
        		rect.bottomRight = new Point(Number(x1), Number(y1));
            	fill(rect);
        }
        
        private function createRoom(rect:Rectangle, index:int=0, array:Array=null):Rectangle
        {
        		var room:Rectangle = new Rectangle();
        		room.left = rect.left + randomRange(2, half(rect.right - rect.left) - 1);
        		room.top = rect.top + randomRange(2, half(rect.bottom - rect.top) - 1);
        		room.right = rect.right - randomRange(2, half(rect.right - rect.left) - 1);
        		room.bottom = rect.bottom - randomRange(2, half(rect.bottom - rect.top) - 1);
        		return room;
        }
        
		private function split(rect:Rectangle, index:int=0, array:Array=null):Array
        {
   			if ((rect.right - rect.left < _margin * 2) || (rect.bottom - rect.top < _margin * 2))
  			{
				return [rect];
			}
        		
        		var rect1:Rectangle = new Rectangle();
        		var rect2:Rectangle = new Rectangle();
        		
        		// 縦(0) or 横(1)
			var direction:int = Math.floor(Math.random() * 2);
			//debug("direction : " + String(direction));
			
			// 分割
			var point:Point = new Point();
			
			// 縦分割
			if(direction)
			{
				point.x = randomRange(rect.left + _margin, rect.right - _margin);
				rect1.topLeft = rect.topLeft;
				rect1.bottomRight = new Point(point.x, rect.bottom);
				rect2.topLeft = new Point(point.x, rect.top);
				rect2.bottomRight = rect.bottomRight;
			}
			else
			{
				point.y =randomRange(rect.top + _margin, rect.bottom - _margin);
				rect1.topLeft = rect.topLeft;
				rect1.bottomRight = new Point(rect.right, point.y);
				rect2.topLeft = new Point(rect.x, point.y);
				rect2.bottomRight = rect.bottomRight;
			}
			
			return [rect1, rect2].map(split);
        }
        
        
    		private function flatten(array:*, tmp:Array):Array
		{
			//debug("flatten");
			for each (var item:* in array)
			{
				if(item as Array) tmp = flatten(item, tmp);
				if(item as Rectangle) tmp.push(item);
			}
			return tmp;
		}
        
        private function debug(message:String, isBreak:Boolean = true):void
        {
        		if (isBreak) message += "\n";
        		_debug.appendText(message);
        }
        
        private function startDebug():void
        {
        	    /**
            * setting debug
            */
            var format:TextFormat = new TextFormat();
            format.font = '_等幅';
            format.size  = _fontSize;
            format.color = 0x000000;
            
            _debug = new TextField();
            _debug.height = 450;
            _debug.width = 400;
            _debug.border = true;
            _debug.text = '\n';
            _debug.setTextFormat(format);
            this.addChild(_debug);        
        }
    }
    
}