不思議のダンジョン自動生成 参考:http://d.hatena.ne.jp/Gemma/20070816 takimo forked:2favorite:0lines:197license : MIT License modified : 2009-12-30 11:38:58 Embed Tweet 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); } } } Code Fullscreen Preview Fullscreen rogue roguelike Rectangle bottomRight Math.min message split Math.max topLeft bottom Array TextFormat top length right Math.floor left String map width height font sort new page view favorite forked pv0 forked from: 不思議のダンジョン自動生成 takimo forked:0 favorite:0lines:197 (diff:1) pv1611 不思議のダンジョン(ダンジョン自動生成&移動&戦闘).. takimo forked:1 favorite:8lines:793 (diff:1039) tag: game rogue roguelike