From c6bbb834f7758027c0df338f1520f34fad3befea Mon Sep 17 00:00:00 2001 From: Matheus Date: Tue, 9 Sep 2025 19:09:34 -0300 Subject: Organização MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/Map/MapDivision.cs | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 scripts/Map/MapDivision.cs (limited to 'scripts/Map/MapDivision.cs') diff --git a/scripts/Map/MapDivision.cs b/scripts/Map/MapDivision.cs new file mode 100644 index 0000000..e50b331 --- /dev/null +++ b/scripts/Map/MapDivision.cs @@ -0,0 +1,113 @@ +using Godot; + +namespace TheLegendOfGustav.Map; + +/// +/// Classe utilizada pelo gerador de mapas. +/// Uma divisão é uma região retangular de espaço que pode +/// conter dentro de si duas regiões menores *ou* uma sala. +/// Uma divisão é uma árvore binária que possui espaço para salas em suas folhas. +/// +public partial class MapDivision : RefCounted +{ + public MapDivision(Vector2I position, Vector2I size) + { + Position = position; + Size = size; + } + + public MapDivision(Vector2I position, int width, int height) + { + Position = position; + Size = new(width, height); + } + + public MapDivision(int x, int y, int width, int height) + { + Position = new(x, y); + Size = new(width, height); + } + + /// + /// Região retangular da divisão. + /// + public Vector2I Position { get; set; } + public Vector2I Size { get; set; } + + public Vector2I Center + { + get => new(Position.X + Size.X / 2, Position.Y + Size.Y / 2); + } + + /// + /// Filhos da árvore + /// + public MapDivision Left { get; private set; } + public MapDivision Right { get; private set; } + + /// + /// Se a divisão atual for uma folha. + /// As folhas representam salas. + /// + public bool IsLeaf + { + get => Left == null && Right == null; + } + + /// + /// É conveniente ter acesso à todas as folhas da árvore. + /// + /// Lista com todas as folhas da árvore. + public Godot.Collections.Array GetLeaves() + { + if (IsLeaf) + { + Godot.Collections.Array list = []; + list.Add(this); + return list; + } + return Left.GetLeaves() + Right.GetLeaves(); + } + + /// + /// Algoritmo para gerar as divisões. + /// O mapa começa com uma única divisão que oculpa sua extensão completa. + /// Depois disso, ela se dividirá recursivamente n vezes. + /// As divisões nas folhas representam espaços onde pode gerar uma sala. + /// + /// Número de iterações + /// Gerador de números + public void Split(int iterations, RandomNumberGenerator rng) + { + float SplitRatio = rng.RandfRange(0.35f, 0.65f); + bool horizontalSplit = Size.X <= Size.Y; + + // Eu defini um limite mínimo de 4 de altura e 4 de largura para divisões. + + if (horizontalSplit) + { + int leftHeight = (int)(Size.Y * SplitRatio); + if (leftHeight > 4 && Size.Y - leftHeight > 4) + { + Left = new MapDivision(Position, Size.X, leftHeight); + Right = new MapDivision(Position.X, Position.Y + leftHeight, Size.X, Size.Y - leftHeight); + } + } + else + { + int leftWidth = (int)(Size.Y * SplitRatio); + + if (leftWidth > 4 && Size.Y - leftWidth > 4) + { + Left = new MapDivision(Position, leftWidth, Size.Y); + Right = new MapDivision(Position.X + leftWidth, Position.Y, Size.X - leftWidth, Size.Y); + } + } + + if (iterations > 1) + { + Left?.Split(iterations - 1, rng); + Right?.Split(iterations - 1, rng); + } + } +} \ No newline at end of file -- cgit v1.2.3