/// <summary> /// Generates a grid with a path carved by a drunkard walk algorithm /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="seed"></param> /// <param name="fillPercentage"></param> /// <returns></returns> public static int[,] Generate(int width, int height, int seed, int fillPercentage, Vector2Int startingPoint, int maxIterations) { int[,] grid = PrepareGrid(ref width, ref height); grid = MMGridGeneratorFull.Generate(width, height, true); System.Random random = new System.Random(seed); int requiredFillQuantity = ((width * height) * fillPercentage) / 100; int fillCounter = 0; int currentX = startingPoint.x; int currentY = startingPoint.y; grid[currentX, currentY] = 0; fillCounter++; int iterationsCounter = 0; while ((fillCounter < requiredFillQuantity) && (iterationsCounter < maxIterations)) { int direction = random.Next(4); switch (direction) { case 0: if ((currentY + 1) < height) { currentY++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 1: if ((currentY - 1) > 1) { currentY--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 2: if ((currentX - 1) > 1) { currentX--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 3: if ((currentX + 1) < width) { currentX++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; } iterationsCounter++; } return(grid); }
/// <summary> /// Generates a grid with a path carved by a drunkard walk algorithm that will avoid another grid's walls /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="seed"></param> /// <param name="fillPercentage"></param> /// <returns></returns> public static int[,] Generate(int width, int height, int seed, int fillPercentage, Vector2Int startingPoint, int[,] obstacles, int obstacleDistance, int maxIterations) { int[,] grid = PrepareGrid(ref width, ref height); grid = MMGridGeneratorFull.Generate(width, height, true); System.Random random = new System.Random(seed); int requiredFillQuantity = ((width * height) * fillPercentage) / 100; int fillCounter = 0; int currentX = startingPoint.x; int currentY = startingPoint.y; grid[currentX, currentY] = 0; fillCounter++; int iterationsCount = 0; while ((fillCounter < requiredFillQuantity) && (iterationsCount < maxIterations)) { int direction = random.Next(4); switch (direction) { case 0: // up if ( ((currentY + 1) <= height) && !ObstacleAt(obstacles, currentX, currentY + obstacleDistance) ) { currentY++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 1: // down if ( ((currentY - 1) > 1) && !ObstacleAt(obstacles, currentX, currentY - obstacleDistance) ) { currentY--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 2: // left if (((currentX - 1) > 1) && !ObstacleAt(obstacles, currentX - obstacleDistance, currentY ) ) { currentX--; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; case 3: // right if (((currentX + 1) <= width) && !ObstacleAt(obstacles, currentX + obstacleDistance, currentY) ) { currentX++; grid = Carve(grid, currentX, currentY, ref fillCounter); } break; } iterationsCount++; } return grid; }
/// <summary> /// Generates a simple grid filled with random points /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="seed"></param> /// <param name="fillPercentage"></param> /// <returns></returns> public static int[,] Generate(int width, int height, int seed, int fillPercentage) { int[,] grid = PrepareGrid(ref width, ref height); grid = MMGridGeneratorFull.Generate(width, height, true); System.Random random = new System.Random(seed); for (int i = 0; i <= width; i++) { for (int j = 0; j <= height; j++) { int value = (random.Next(0, 100) < fillPercentage)? 1: 0; SetGridCoordinate(grid, i, j, value); } } return(grid); }
/// <summary> /// Generates a layer grid, and renders it /// </summary> /// <param name="layer"></param> protected virtual void GenerateLayer(MMTilemapGeneratorLayer layer) { if (!layer.Active) { return; } if (layer.TargetTilemap == null) { Debug.LogError("Tilemap Generator : you need to specify a Target Tilemap to paint on."); } if (layer.Tile == null) { Debug.LogError("Tilemap Generator : you need to specify a Tile to paint with."); } if (layer.GridWidth == 0) { Debug.LogError("Tilemap Generator : grid width can't be 0."); } if (layer.GridHeight == 0) { Debug.LogError("Tilemap Generator : grid height can't be 0."); } float seedFloat = 0f; float layerSeedFloat = 0f; float globalSeedFloat = 0f; UnityEngine.Random.InitState(GlobalSeed); int width = layer.OverrideGridSize ? layer.GridWidth : UnityEngine.Random.Range(GridWidth.x, GridWidth.y); int height = layer.OverrideGridSize ? layer.GridHeight : UnityEngine.Random.Range(GridHeight.x, GridHeight.y); globalSeedFloat = UnityEngine.Random.value; // random outside of the global seed if (layer.DoNotUseGlobalSeed) { Random.InitState((int)System.DateTime.Now.Ticks); if (layer.RandomizeSeed) { layer.Seed = Mathf.Abs(Random.Range(int.MinValue, int.MaxValue)); } UnityEngine.Random.InitState(layer.Seed); layerSeedFloat = UnityEngine.Random.value; } int seed = layer.DoNotUseGlobalSeed ? layer.Seed : GlobalSeed; seedFloat = layer.DoNotUseGlobalSeed ? layerSeedFloat : globalSeedFloat; switch (layer.GenerateMethod) { case GenerateMethods.Full: _grid = MMGridGeneratorFull.Generate(width, height, layer.FullGenerationFilled); layer.Grid = _grid; break; case GenerateMethods.Perlin: _grid = MMGridGeneratorPerlinNoise.Generate(width, height, seedFloat); layer.Grid = _grid; break; case GenerateMethods.PerlinGround: _grid = MMGridGeneratorPerlinNoiseGround.Generate(width, height, seedFloat); layer.Grid = _grid; break; case GenerateMethods.Random: _grid = MMGridGeneratorRandom.Generate(width, height, seed, layer.RandomFillPercentage); layer.Grid = _grid; break; case GenerateMethods.RandomWalk: _grid = MMGridGeneratorRandomWalk.Generate(width, height, seed, layer.RandomWalkPercent, layer.RandomWalkStartingPoint, layer.RandomWalkMaxIterations); layer.Grid = _grid; break; case GenerateMethods.RandomWalkAvoider: int[,] obstacleGrid = MMGridGenerator.TilemapToGrid(layer.RandomWalkAvoiderObstaclesTilemap, width, height); _grid = MMGridGeneratorRandomWalkAvoider.Generate(width, height, seed, layer.RandomWalkAvoiderPercent, layer.RandomWalkAvoiderStartingPoint, obstacleGrid, layer.RandomWalkAvoiderObstaclesDistance, layer.RandomWalkAvoiderMaxIterations); layer.Grid = _grid; break; case GenerateMethods.RandomWalkGround: _grid = MMGridGeneratorRandomWalkGround.Generate(width, height, seed, layer.RandomWalkGroundMinHeightDifference, layer.RandomWalkGroundMaxHeightDifference, layer.RandomWalkGroundMinFlatDistance, layer.RandomWalkGroundMaxFlatDistance, layer.RandomWalkGroundMaxHeight); layer.Grid = _grid; break; case GenerateMethods.Path: _grid = MMGridGeneratorPath.Generate(width, height, seed, layer.PathDirection, layer.PathStartPosition, layer.PathMinWidth, layer.PathMaxWidth, layer.PathDirectionChangeDistance, layer.PathWidthChangePercentage, layer.PathDirectionChangePercentage); layer.Grid = _grid; break; case GenerateMethods.Copy: layer.TargetTilemap.ClearAllTiles(); DelayedCopy(layer); break; } if (layer.Smooth) { _grid = MMGridGenerator.SmoothenGrid(_grid); } if (layer.InvertGrid) { _grid = MMGridGenerator.InvertGrid(_grid); } _grid = MMGridGenerator.BindGrid(_grid, layer.BoundsTop, layer.BoundsBottom, layer.BoundsLeft, layer.BoundsRight); _grid = MMGridGenerator.ApplySafeSpots(_grid, layer.SafeSpots); RenderGrid(layer); }
/// <summary> /// Generates a grid with a path in the specified direction /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="seed"></param> /// <param name="direction"></param> /// <param name="startPosition"></param> /// <param name="pathMinWidth"></param> /// <param name="pathMaxWidth"></param> /// <param name="directionChangeDistance"></param> /// <param name="widthChangePercentage"></param> /// <param name="directionChangePercentage"></param> /// <returns></returns> public static int[,] Generate(int width, int height, int seed, Directions direction, Vector2Int startPosition, int pathMinWidth, int pathMaxWidth, int directionChangeDistance, int widthChangePercentage, int directionChangePercentage) { int[,] grid = PrepareGrid(ref width, ref height); grid = MMGridGeneratorFull.Generate(width, height, true); System.Random random = new System.Random(seed); Random.InitState(seed); int pathWidth = 1; int initialX = startPosition.x; int initialY = startPosition.y; SetGridCoordinate(grid, initialX, initialY, 0); switch (direction) { case Directions.TopToBottom: int x1 = initialX; for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x1 + i, initialY, 0); } for (int y = initialY; y > 0; y--) { pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth); x1 = DetermineNextStep(random, x1, directionChangeDistance, directionChangePercentage, pathMaxWidth, width); for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x1 + i, y, 0); } } break; case Directions.BottomToTop: int x2 = initialX; for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x2 + i, initialY, 0); } for (int y = initialY; y < height; y++) { pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth); x2 = DetermineNextStep(random, x2, directionChangeDistance, directionChangePercentage, pathMaxWidth, width); for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x2 + i, y, 0); } } break; case Directions.LeftToRight: int y1 = initialY; for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, initialX, y1 + i, 0); } for (int x = initialX; x < width; x++) { pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth); y1 = DetermineNextStep(random, y1, directionChangeDistance, directionChangePercentage, pathMaxWidth, width); for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x, y1 + i, 0); } } break; case Directions.RightToLeft: int y2 = initialY; for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, initialX, y2 + i, 0); } for (int x = initialX; x > 0; x--) { pathWidth = ComputeWidth(random, widthChangePercentage, pathMinWidth, pathMaxWidth, pathWidth); y2 = DetermineNextStep(random, y2, directionChangeDistance, directionChangePercentage, pathMaxWidth, width); for (int i = -pathWidth; i <= pathWidth; i++) { SetGridCoordinate(grid, x, y2 + i, 0); } } break; } return(grid); }