private IEnumerator GenerateLevel() { if (lvlWidth <= 0) { Debug.LogError($"Can't generate a level with {lvlWidth} width"); Status = LevelGenerationStatus.Abort; yield break; } if (lvlHeight <= 0) { Debug.LogError($"Can't generate a level with {lvlHeight} height"); Status = LevelGenerationStatus.Abort; yield break; } Status = LevelGenerationStatus.Idle; genProgressionPrev = -1; genProgression = 0; rnd = new System.Random(DateTime.Now.Millisecond); Debug.Log($"Generating level {lvlWidth}x{lvlHeight}"); newLevel = new GridXY <Element>(); newLevel.CreateGridXY(lvlWidth, lvlHeight, 1, Vector3.zero, false, Element.NULL, Element.NULL); LevelNavigation.SetUp(lvlWidth, lvlHeight, true, false); Status = LevelGenerationStatus.Generating; yield return(null); List <Vector2Int> nodes = new List <Vector2Int>(); Coroutine generatingNodes = StartCoroutine(GenerateNodes(Mathf.RoundToInt(Mathf.Clamp((lvlWidth * lvlHeight) * (nodesPercentage / 100f), 2, newLevel.Size)), (generatedNodes) => { nodes = generatedNodes; })); yield return(generatingNodes); yield return(null); int pathsNum = 0; Coroutine generatingPaths = StartCoroutine(GeneratePaths(nodes, (generatedPathsNum) => { pathsNum = generatedPathsNum; })); yield return(generatingPaths); yield return(null); if (pathsNum > 0) { Status = LevelGenerationStatus.Completed; } else { Status = LevelGenerationStatus.Abort; } }
/// <summary> /// Load a new level /// </summary> /// <param name="newLevel">New level.</param> public void LoadLevel(GridXY <Element> newLevel) { if (newLevel == null || newLevel.Size == 0) { Debug.LogWarning("The new level grid is not valid"); return; } Debug.Log($"0. Loading level {newLevel.Width}x{newLevel.Height}..."); ClearLevel(); Debug.Log($"1. Initializing level..."); Grid.CreateGridXY(newLevel.Width, newLevel.Height, 1, Vector3.zero, true, Element.NULL, Element.NULL); Debug.Log("Level is not playable!"); LvlState = LevelState.NotPlayable; OnLevelNotPlayable?.Invoke(this, null); Debug.Log("2. Generating level..."); StartCell = Vector2Int.one * -1; EndCell = Vector2Int.one * -1; bool hasStart = false; bool hasEnd = Grid.Size == 1; Element type; for (int x = 0; x < Grid.Width; x++) { for (int y = 0; y < Grid.Height; y++) { type = newLevel.GetTile(x, y); if (showDebugLog) { Debug.Log($"Setted Tile {x},{y} ({type})"); } Grid.SetTile(x, y, type); if (type == Element.Start) { StartCell = new Vector2Int(x, y); hasStart = true; } else { if (type == Element.End) { EndCell = new Vector2Int(x, y); hasEnd = true; } } } } Debug.Log("Level is ready!"); LvlState = LevelState.Ready; OnLevelReady?.Invoke(this, new OnLevelReadyEventArgs { width = Grid.Width, height = Grid.Height }); if (!hasStart || !hasEnd) { Debug.LogWarning($"Level has {(!hasStart ? "NO": "")} Start and {(!hasEnd ? "NO" : "")} End"); return; } LevelNavigation.SetUp(Grid.Width, Grid.Height, false, true, Grid); Debug.Log("Level is playable!"); LvlState = LevelState.Playable; OnLevelPlayable?.Invoke(this, new OnLevelPlayableEventArgs { startX = StartCell.x, startY = StartCell.y, endX = EndCell.x, endY = EndCell.y }); OnLevelStart?.Invoke(); }