
Leaf object that we use to divide an area into small segments. Then we will generate a random room in each Leaf . And finally, learn how to connect all the rooms corridors.Leaf , and then draws them in the BitmapData object, after which it is displayed on the screen (zooming in to fill the screen).
Bitmap map to the FlxTilemap object, which generates a playable tile map and displays it on the screen. You can wander through it using the arrows:
Leaf ), and divide it vertically or horizontally into two smaller sheets, and then repeat the process with smaller areas, again and again, until each area is less than or equal to the specified maximum value.Leaf , with which you can do anything. In 3D graphics, BSP can be used to sort objects visible to the player or to recognize collisions in even smaller parts.Leaf class. In essence, our Leaf will be a rectangle with some additional features. Each Leaf will contain either a pair of Leaf subsidiaries, or a pair of Room rooms, as well as one or two corridors.Leaf code looks like: public class Leaf { private const MIN_LEAF_SIZE:uint = 6; public var y:int, x:int, width:int, height:int; // public var leftChild:Leaf; // Leaf public var rightChild:Leaf; // Leaf public var room:Rectangle; // , public var halls:Vector.; // , public function Leaf(X:int, Y:int, Width:int, Height:int) { // x = X; y = Y; width = Width; height = Height; } public function split():Boolean { // if (leftChild != null || rightChild != null) return false; // ! ! // // 25% , // 25% , // var splitH:Boolean = FlxG.random() > 0.5; if (width > height && width / height >= 1.25) splitH = false; else if (height > width && height / width >= 1.25) splitH = true; var max:int = (splitH ? height : width) - MIN_LEAF_SIZE; // if (max <= MIN_LEAF_SIZE) return false; // , ... var split:int = Registry.randomNumber(MIN_LEAF_SIZE, max); // , // if (splitH) { leftChild = new Leaf(x, y, width, split); rightChild = new Leaf(x, y + split, width, height - split); } else { leftChild = new Leaf(x, y, split, height); rightChild = new Leaf(x + split, y, width - split, height); } return true; // ! } } Leaf : const MAX_LEAF_SIZE:uint = 20; var _leafs:Vector<Leaf> = new Vector<Leaf>; var l:Leaf; // // , "" . var root:Leaf = new Leaf(0, 0, _sprMap.width, _sprMap.height); _leafs.push(root); var did_split:Boolean = true; // Vector, , . while (did_split) { did_split = false; for each (l in _leafs) { if (l.leftChild == null && l.rightChild == null) // ... { // , 75%... if (l.width > MAX_LEAF_SIZE || l.height > MAX_LEAF_SIZE || FlxG.random() > 0.25) { if (l.split()) // ! { // , Vector, _leafs.push(l.leftChild); _leafs.push(l.rightChild); did_split = true; } } } } } Vector (typed array) filled with leaves.
Leaf and go down to the smallest Leaf that do not have child leaves, and then create a room in each of them.Leaf class: public function createRooms():void { // . if (leftChild != null || rightChild != null) { // , if (leftChild != null) { leftChild.createRooms(); } if (rightChild != null) { rightChild.createRooms(); } } else { // var roomSize:Point; var roomPos:Point; // 3 x 3 - 2. roomSize = new Point(Registry.randomNumber(3, width - 2), Registry.randomNumber(3, height - 2)); // , // ( ) roomPos = new Point(Registry.randomNumber(1, width - roomSize.x - 1), Registry.randomNumber(1, height - roomSize.y - 1)); room = new Rectangle(x + roomPos.x, y + roomPos.y, roomSize.x, roomSize.y); } } Vector from leaves, let's call our new function from the root leaf: _leafs = new Vector<Leaf>; var l:Leaf; // // , "" . var root:Leaf = new Leaf(0, 0, _sprMap.width, _sprMap.height); _leafs.push(root); var did_split:Boolean = true; // Vector, , . while (did_split) { did_split = false; for each (l in _leafs) { if (l.leftChild == null && l.rightChild == null) // ... { // , 75%... if (l.width > MAX_LEAF_SIZE || l.height > MAX_LEAF_SIZE || FlxG.random() > 0.25) { if (l.split()) // ! { // , Vector, _leafs.push(l.leftChild); _leafs.push(l.rightChild); did_split = true; } } } } } // . root.createRooms(); 

public function getRoom():Rectangle { // , , . if (room != null) return room; else { var lRoom:Rectangle; var rRoom:Rectangle; if (leftChild != null) { lRoom = leftChild.getRoom(); } if (rightChild != null) { rRoom = rightChild.getRoom(); } if (lRoom == null && rRoom == null) return null; else if (rRoom == null) return lRoom; else if (lRoom == null) return rRoom; else if (FlxG.random() > .5) return lRoom; else return rRoom; } } public function createHall(l:Rectangle, r:Rectangle):void { // . // , , , , . // , , . halls = new Vector<Rectangle>; var point1:Point = new Point(Registry.randomNumber(l.left + 1, l.right - 2), Registry.randomNumber(l.top + 1, l.bottom - 2)); var point2:Point = new Point(Registry.randomNumber(r.left + 1, r.right - 2), Registry.randomNumber(r.top + 1, r.bottom - 2)); var w:Number = point2.x - point1.x; var h:Number = point2.y - point1.y; if (w < 0) { if (h < 0) { if (FlxG.random() < 0.5) { halls.push(new Rectangle(point2.x, point1.y, Math.abs(w), 1)); halls.push(new Rectangle(point2.x, point2.y, 1, Math.abs(h))); } else { halls.push(new Rectangle(point2.x, point2.y, Math.abs(w), 1)); halls.push(new Rectangle(point1.x, point2.y, 1, Math.abs(h))); } } else if (h > 0) { if (FlxG.random() < 0.5) { halls.push(new Rectangle(point2.x, point1.y, Math.abs(w), 1)); halls.push(new Rectangle(point2.x, point1.y, 1, Math.abs(h))); } else { halls.push(new Rectangle(point2.x, point2.y, Math.abs(w), 1)); halls.push(new Rectangle(point1.x, point1.y, 1, Math.abs(h))); } } else // (h == 0) { halls.push(new Rectangle(point2.x, point2.y, Math.abs(w), 1)); } } else if (w > 0) { if (h < 0) { if (FlxG.random() < 0.5) { halls.push(new Rectangle(point1.x, point2.y, Math.abs(w), 1)); halls.push(new Rectangle(point1.x, point2.y, 1, Math.abs(h))); } else { halls.push(new Rectangle(point1.x, point1.y, Math.abs(w), 1)); halls.push(new Rectangle(point2.x, point2.y, 1, Math.abs(h))); } } else if (h > 0) { if (FlxG.random() < 0.5) { halls.push(new Rectangle(point1.x, point1.y, Math.abs(w), 1)); halls.push(new Rectangle(point2.x, point1.y, 1, Math.abs(h))); } else { halls.push(new Rectangle(point1.x, point2.y, Math.abs(w), 1)); halls.push(new Rectangle(point1.x, point1.y, 1, Math.abs(h))); } } else // (h == 0) { halls.push(new Rectangle(point1.x, point1.y, Math.abs(w), 1)); } } else // (w == 0) { if (h < 0) { halls.push(new Rectangle(point2.x, point2.y, 1, Math.abs(h))); } else if (h > 0) { halls.push(new Rectangle(point1.x, point1.y, 1, Math.abs(h))); } } } createRooms() function to createRooms() function for each sheet that has a pair of child leaves: public function createRooms():void { // . if (leftChild != null || rightChild != null) { // , if (leftChild != null) { leftChild.createRooms(); } if (rightChild != null) { rightChild.createRooms(); } // , , if (leftChild != null && rightChild != null) { createHall(leftChild.getRoom(), rightChild.getRoom()); } } else { // var roomSize:Point; var roomPos:Point; // 3 x 3 - 2. roomSize = new Point(Registry.randomNumber(3, width - 2), Registry.randomNumber(3, height - 2)); // , ( ) roomPos = new Point(Registry.randomNumber(1, width - roomSize.x - 1), Registry.randomNumber(1, height - roomSize.y - 1)); room = new Rectangle(x + roomPos.x, y + roomPos.y, roomSize.x, roomSize.y); } } 
Leaf object that can be used to generate a tree of separated leaves, created random rooms in each of the leaves, and connected rooms with corridors.Source: https://habr.com/ru/post/332832/
All Articles