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

ローグライクマップ 生成

ローグライクマップ
工程の再現アニメーションが途中・・
大きさの制御が適当
Get Adobe Flash player
by kenbu 15 Jun 2009
/**
 * Copyright kenbu ( http://wonderfl.net/user/kenbu )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1e3V
 */

/**
    ローグライクマップ
    工程の再現アニメーションが途中・・
    大きさの制御が適当
*/

package 
{ 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 
    import flash.geom.Rectangle; 
    import flash.geom.Point; 
     
    

    public class Main extends Sprite 
    { 
         
        private var map:RogueLikeMap; 
        private var bitmap:Bitmap; 
         
        private const WIDTH:Number = 90; 
        private const HEIGHT:Number = 90; 
        private const SCALE:Number = 5; 
         
        public function Main() 
        { 
            stage.scaleMode = StageScaleMode.NO_SCALE; 
            stage.align = StageAlign.TOP_LEFT; 
             
            var progressArray:Array = []; 
            map = new RogueLikeMap(WIDTH,HEIGHT, 4,4,5,progressArray); 
             
            var bitmapData:BitmapData = new BitmapData(WIDTH*SCALE, HEIGHT*SCALE); 
            bitmap = new Bitmap(bitmapData); 
            addChild(bitmap); 
             
         
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler); 
        } 
         
         

        private var cnt:int = 0; 
        private function enterFrameHandler(event:Event):void 
        { 
            var l:int = 100; 
            for(var i:int = 0; i<l; i++) 
            { 
                draw(); 
            } 
            if(cnt == map.buildProgressArray.length) 
            { 
                this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler); 
            } 
        } 
         
         
        private var rect:Rectangle = new Rectangle(0,0,0,0); 
        private function draw():void 
        { 
            if(cnt == map.buildProgressArray.length) 
            { 
                return; 
            } 
             
            var point:Object= map.buildProgressArray[cnt]; 
            var color:Number; 
            if(point.value == 0) 
            { 
                color = 0xffffffff; 
            } 
            else 
            { 
                color = 0xff000000; 
            } 
            var scale:Number = 3; 
             
            var bitmapData:BitmapData = bitmap.bitmapData; 
             
            rect.x = point.x * SCALE; 
            rect.y = point.y * SCALE; 
            rect.width = SCALE; 
            rect.height = SCALE; 
             
             
            bitmapData.fillRect(rect, color); 

             
            cnt++; 


         
        } 
    } 
} 


	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	class RogueLikeMap
	{
		
		private var rectArray:Array;
		private var roomArray:Array;
		private var roadArray:Array;
		
		public var width:uint;
		public var height:uint;
		
		private var minRoomWidth:uint;
		private var minRoomHeight:uint;
		
		private var maxCouple:uint;
		
		public var data:Array;
		
	
		public var buildProgressArray:Array;
		
		public function RogueLikeMap(width:uint, height:uint, minRoomWidth:uint, minRoomHieght:uint, maxCouple:uint, buildProgressArray:Array = null)
		{
			//minRoomWidth	最小の部屋のサイズ width
			//minRoomHeight 最小の部屋のサイズ height
			//maxCouple		最大分割数。
			
			this.width = width;
			this.height = height;
			this.minRoomWidth = minRoomWidth;
			this.minRoomHeight = minRoomHieght;
			this.maxCouple = maxCouple;

			this.buildProgressArray = buildProgressArray;

			initialize();	
			
			
		}
		
		private function initialize():void
		{
			data = [];
			rectArray = [];
			roomArray = [];
			roadArray = [];
			
			
			setRect(new Rect(0,0,width, height, (Math.random()>0.5)));
			setRoom();
			setRoad();
			setDataArray();
		
		}
		

		private var splitCnt:int;
		private function setRect(rect:Rect):void
		{
			if(maxCouple <= splitCnt++)
			{
				return;
			}
			
			var x:uint = rect.x;
			var y:uint = rect.y;
			var w:uint = rect.width;
			var h:uint = rect.height;
			
			
			rectArray.push(rect);
			
			//分割する
			var nowRect:Rect;
			if(rect.splitAline)
			{
				//縦に分割
				var _x:uint = uint(w/2);
				rect.width = _x;
				nowRect = new Rect(x+_x, y, w-_x, h, !rect.splitAline);
				setRect(nowRect);
			}
			else
			{
				//横に分割
				var _y:uint = int(h/2);
				rect.height = _y;
				nowRect = new Rect(x, y+_y, w, h-_y, !rect.splitAline);
				setRect(nowRect);
			}
			
			

		}

		private function setRoom():void
		{
			rectArray.forEach(function(rect:Rect, i:int, array:Array):void{
				var room:Rectangle = new Rectangle(rect.x, rect.y, rect.width, rect.height);
				
				var w:uint = ((room.width-2) - minRoomWidth)*Math.random() + minRoomWidth;
				var h:uint = ((room.height-2) - minRoomHeight)*Math.random() + minRoomHeight;
				
				room.x =  room.x + int((rect.width - w)/2);
				room.y =  room.y + int((rect.height - h)/2);
				room.width = w;
				room.height = h;
				
				
				roomArray.push(room);
			});
		}

		public function setRoad():void
		{
			//道を引く。
			var prevRoomRect:Rectangle;
			rectArray.forEach(function(rect:Rect, i:int, arr:Array):void{
				//一個目は飛ばす。
				if(i > 0)
				{
					var road:Road;
					var prev:Rect = arr[i-1];
					
					var room:Rectangle = roomArray[i];
					var prevRoom:Rectangle = roomArray[i-1];
					
					//中継点
					var x0:uint;
					var x1:uint;
					var y0:uint;
					var y1:uint;
					
					
					if(rect.x < prev.x)
					{
						//ターゲットが右側。
						//始点、
						//終点
						y0 = getRadomPos(room.y, room.height);
						y1 = getRadomPos(prevRoom.y, prevRoom.height);
						road = new Road(
							//始点
							
							new Point(room.x + room.width, y0),
							//中継点
							new Point(rect.x+rect.width, y0),
							new Point(rect.x+rect.width, y1),
							new Point(prevRoom.x, y1)
						);

					}
					else if(rect.x > prev.x)
					{
						//ターゲットが左側
						y0 = getRadomPos(room.y, room.height);
						y1 = getRadomPos(prevRoom.y, prevRoom.height);
						road = new Road(
							//始点
							
							new Point(room.x, y0),
							//中継点
							new Point(rect.x, y0),
							new Point(rect.x, y1),
							new Point(prevRoom.x+prevRoom.width, y1)
						);
					}
					else if(rect.y > prev.y )
					{
						//ターゲットが上
						x0 = getRadomPos(room.x, room.width);
						x1 = getRadomPos(prevRoom.x, prevRoom.width);
						road = new Road(
							//始点
							
							new Point(x0, room.y),
							//中継点
							new Point(x0, rect.y),
							new Point(x1, rect.y),
							new Point(x1,  prevRoom.y+prevRoom.height)
						);

					
					}
					else
					{
						//ターゲット下
						x0 = getRadomPos(room.x, room.width);
						x1 = getRadomPos(prevRoom.x, prevRoom.width);
						road = new Road(
							//始点
							
							new Point(x0, room.y + room.height),
							//中継点
							new Point(x0,rect.y+rect.height),
							new Point(x1, rect.y+rect.height),
							new Point(x1, prevRoom.y)
						);
					}
					roadArray.push(road);
				}
					
			});
			
		}
		
		private function getRadomPos(x:uint, w:uint):uint
		{
			//x ~  (x + w) の間のランダムな数値を返す。
			var _w:int = int((w-1)*Math.random())
			return x + _w + 1;
		}
		
		private function setDataArray():void
		{
			//壁を生成
			var l:int = width * height;
			for(var i:int = 0; i<l; i++)
			{
				setData(i%width, int(i/width), 1);
			}
			
			//部屋を生成
			roomArray.forEach(function(rect:Rectangle, i:int, arr:Array):void
			{	
				var n:int = rect.y + rect.height;
				for(var y:int = rect.y; y<n; y++)
				{
					var l:int = rect.x + rect.width;
					for(var x:int = rect.x; x<l; x++)
					{
						setData(x, y, 0);
					}
				}
			});
			
			//道を生成
			roadArray.forEach(function(road:Road,i:int, arr:Array):void{
				road.points.forEach(function(p:Point, i:int, array:Array):void{
					if(i != 0)
					{
						setDataRoad(array[i-1], array[i]);
					}
				});
				
			});
		}
		
		
		private function setDataRoad(point1:Point, point2:Point):void
		{
			//2点間を線でつなぎます。
			
			if(point1.y == point2.y)
			{
				var l:int = (point1.x - point2.x);
				var dirX:int = (l>0)?1:-1;
				l = (l>0)?l:-l;
				
				for(var i:int = 0; i<l; i++)
				{
					var x:uint = point2.x + dirX*i;
					setData(x,point1.y,0);
				}
			}
			else
			{
				var n:int = (point1.y - point2.y);
				var dirY:int = (n>0)?1:-1;
				n = (n>0)?n:-n;
	
				for(var j:int = 0; j<n; j++)
				{
					var y:uint = point2.y + dirY*j;
					setData(point1.x,y,0);
				}
			}
			
		}
		
		
		private function setData(x:uint, y:uint, value:uint):void
		{
			data[x+width*y] = value;
			if(buildProgressArray)
			{
				buildProgressArray.push({x:x, y:y, value:value});
			}
		}

		public function dump():Sprite
		{
			
			var sprite:Sprite = new Sprite();
			
			return sprite;
			
			var g:Graphics = sprite.graphics;
			g.lineStyle(1);
			rectArray.forEach(function(rect:Rectangle, i:int, arr:Array):void
			{	
				g.drawRect(rect.x, rect.y, rect.width, rect.height);
			});
			
			roomArray.forEach(function(rect:Rectangle, i:int, arr:Array):void
			{	
				g.beginFill(0xff0000);
				g.drawRect(rect.x, rect.y, rect.width, rect.height);
			});
			g.endFill();
			//道を引く

			g.lineStyle(1, 0xff00ff);
			roadArray.forEach(function(road:Road,i:int, arr:Array):void{
				g.moveTo(road.points[0].x,road.points[0].y);
				g.lineTo(road.points[1].x,road.points[1].y);
				g.lineTo(road.points[2].x,road.points[2].y);
				g.lineTo(road.points[3].x,road.points[3].y);
			});

			var traceLine:String = "";
			var cnt:int = 0;
			data.forEach(function(v:uint, i:int, arr:Array):void{
				traceLine += v+""
				cnt++;
				if(cnt%width == 0)
				{
					traceLine ="";
					cnt = 0;
				}
			});

			return sprite;
		}

	}

	class Rect extends Rectangle
	{

		public var splitAline:Boolean;
		public function Rect(x:Number, y:Number, width:Number, height:Number ,splitAline:Boolean)
		{
			super(x, y, width, height);
			this.splitAline = splitAline;
		}
        }
	class Road
	{
	
		public var points:Array;
		

		public function Road(startPoint:Point, jointPoint1:Point, jointPoint2:Point, endPoint:Point)
		{
			points = [startPoint, jointPoint1, jointPoint2, endPoint];
		}
		

	}