コード例 #1
0
    // Načte scénu s generátorem mapy (scéna s postavou je načtena) a odnačte scénu s výběrem úrovní
    IEnumerator LoadMazeAsync(string locationSceneName, MazeSettingsSO mazeSettings)
    {
        _loading = true;
        _loadingScreen.ShowLoadingScreen();
        Player.SetActive(false);
        CurrentHubManager  = null;
        CurrentMazeManager = null;
        AsyncOperation locationSceneLoadingTask = SceneManager.LoadSceneAsync(locationSceneName, LoadSceneMode.Additive);

        while (!locationSceneLoadingTask.isDone)
        {
            yield return(null);
        }

        SceneManager.SetActiveScene(SceneManager.GetSceneByName(locationSceneName));

        while (CurrentMazeManager == null)
        {
            yield return(null);
        }

        string message = CurrentMazeManager.CreateMaze(mazeSettings);

        QuestUI.QueueMessage(message);

        CurrentHubManager = null;
        UnloadScene(HUB_SCENE_NAME);

        Player.SetActive(true);
        _loading = false;
        _loadingScreen.HideLoadingScreen();
    }
コード例 #2
0
    // Vytvoří uzly k vyhledávání cesty podle podbuňek, které dostane v objektu Subcell Data
    public PathfindingNode[] GenerateNodes(MazeSettingsSO mazeSettings, SubcellData subcellData)
    {
        _pathfindingNodes  = new PathfindingNode[subcellData.EmptySpotInArray * mazeSettings.pathfindingNodesInSubcell * mazeSettings.pathfindingNodesInSubcell];
        _currentEmptyIndex = 0;
        float   step = mazeSettings.distanceBetweenCells / mazeSettings.pathfindingNodesInSubcell * mazeSettings.nodeSpreadPercentage;
        Vector3 startPosition;
        Vector3 startOffset = new Vector3(((float)mazeSettings.distanceBetweenCells * mazeSettings.nodeSpreadPercentage - step) / 2f, 0, ((float)mazeSettings.distanceBetweenCells * mazeSettings.nodeSpreadPercentage - step) / 2f);

        foreach (Subcell subcell in subcellData.Subcells)
        {
            if (subcell == null)
            {
                continue;
            }

            // Projde všechny buňky a vytvoří v nich uzly k vyhledávání cesty
            subcell.LowestPathfindingNodeID = _currentEmptyIndex;
            startPosition = subcell.Position - startOffset;
            CreatePathfindingNodeGrid(startPosition, mazeSettings.pathfindingNodesInSubcell, step);

            ConnectNodesInSubcellToNeighbours(subcell, mazeSettings.pathfindingNodesInSubcell);
            subcell.NodesCreated = true;
        }

        return(_pathfindingNodes);
    }
コード例 #3
0
    // Přesvědčí se, zda se už něco nenačítá a poté zavolá Coroutine, která načte scénu, která vygeneruje mapu
    public void EnterMaze(MazeSettingsSO mazeSettings)
    {
        if (_loading)
        {
            return;
        }

        Player.GetComponent <PlayerController>().ResetStatsAndCleanInventory();

        StartCoroutine(LoadMazeAsync(MAP_SCENE_NAME, mazeSettings));
    }
コード例 #4
0
    // Vygeneruje mapu, jako parametry přijíma Maze Settings a IWinCondition, jinými slovy pravidla, jak se má mapa generovat, a podmínku pro splnění úrovně
    public PathfindingNode[] GenerateMaze(MazeSettingsSO mazeSettings, IWinCondition winCondition, out int nodeCount)
    {
        _mazeSettings     = mazeSettings;
        _winCondition     = winCondition;
        _generationsRules = _winCondition.SpecialGenerationRules();

        // Vygeneruje buňky, pokud jich vygeneruje málo může generaci opakovat
        ICellGenerator cellGenerator = GetComponent <ICellGenerator>();

        _startPoint = new Vector3(_mazeSettings.centerPoint.x - ((float)_mazeSettings.width / 2f) * _mazeSettings.distanceBetweenCells, _mazeSettings.centerPoint.y, _mazeSettings.centerPoint.z - ((float)_mazeSettings.length / 2f) * _mazeSettings.distanceBetweenCells); // RLpos

        int generationCounter = 0;

        while (generationCounter < _mazeSettings.triesToGenerateMaze)
        {
            _cellData = cellGenerator.GenerateCells(_mazeSettings, _startPoint);
            if ((float)_cellData.CellCount / (float)(_mazeSettings.length * _mazeSettings.width) >= _mazeSettings.minCellPercentage)
            {
                break;
            }
            generationCounter++;
        }

        // Rozdělí buňky na podbuňky
        ISubcellGenerator subcellGenerator = GetComponent <ISubcellGenerator>();

        _subcellData = subcellGenerator.GenerateSubcells(_mazeSettings, _cellData, _startPoint, 1);

        // Pokud je u podmínky k zvítězení pravidlo na vedlejší místnost, tak ji vygeneruje
        if (_generationsRules.Contains(GenerationRule.OuterRoom))
        {
            CreateOuterRoom();
        }

        // Vytvoří na mapě části místností pro všechny podbuňky
        ITileGenerator tileGenerator = GetComponent <TileGenerator>();

        tileGenerator.GenerateTiles(_subcellData, _generationsRules.Contains(GenerationRule.OuterRoom) ? (_subcellData.EmptySpotInArray - 1) : _subcellData.EmptySpotInArray);

        // Vytvoří vrcholy pro hledání cesty
        PathfindingNodeGenerator pathfindingNodeGenerator = GetComponent <PathfindingNodeGenerator>();

        _pathfindingNodes = pathfindingNodeGenerator.GenerateNodes(_mazeSettings, _subcellData);

        GetComponent <Spawner>().SpawnReturnPortal(_subcellData.SpawnPoint);
        GameManager.Instance.Player.transform.position = new Vector3(_subcellData.SpawnPoint.x, _subcellData.SpawnPoint.y + _playerYOffset, _subcellData.SpawnPoint.z);

        SpawnEnemies();

        nodeCount = _pathfindingNodes.Length;
        return(_pathfindingNodes);
    }
コード例 #5
0
    // Vytvoří podbuňky podle pravidel v Maze Settings
    public SubcellData GenerateSubcells(MazeSettingsSO mazeSettings, CellData cellData, Vector3 startPoint, int additionalArraySize)
    {
        _mazeSettings = mazeSettings;
        _cellData     = cellData;
        _startPoint   = startPoint;

        _emptySpotInArray = 0;
        _subcells         = new Subcell[_cellData.MaximumSubcellCount + additionalArraySize];
        Stack <Vector2Int> cellStack = new Stack <Vector2Int>();

        // Vezme první buňku, vytvoří v ní podbuňky a vloží sousední buňky do zásobníku
        Vector3 spawnPoint = new Vector3(startPoint.x + (float)_cellData.XDistance[_cellData.FirstCell.y] * _mazeSettings.distanceBetweenCells, startPoint.y, startPoint.z + (float)_cellData.ZDistance[_cellData.FirstCell.x] * _mazeSettings.distanceBetweenCells); // RLpos

        CreateRoom(_cellData.FirstCell);
        PushNeighbouringCellsIntoStack(cellStack, _cellData.FirstCell);
        _cellData.Cells[_cellData.FirstCell.x, _cellData.FirstCell.y].generated = true;

        // Rozděluje buňky na podbuňky a vkládá do zásobníku sousední buňky, dokud zásobník není prázdný
        Vector2Int currentCell; // Z, X

        while (cellStack.Count > 0)
        {
            currentCell = cellStack.Pop();
            if (_cellData.Cells[currentCell.x, currentCell.y].generated == true)
            {
                continue;
            }

            // Náhodně vybere, jestli to bude místnost nebo chodba
            if (Random.Range(0f, 1f) <= _mazeSettings.roomChance[_cellData.Cells[currentCell.x, currentCell.y].GetDoorCount() - 1])
            {
                CreateRoom(currentCell);
            }
            else
            {
                CreateCorridor(currentCell);
            }

            PushNeighbouringCellsIntoStack(cellStack, currentCell);
            _cellData.Cells[currentCell.x, currentCell.y].generated = true;
        }

        return(new SubcellData(_subcells, _emptySpotInArray, spawnPoint));
    }
コード例 #6
0
    // Přidá jeden komponent implementující interface Win Condition podle nastavení v Maze Settings
    public string CreateMaze(MazeSettingsSO mazeSettings)
    {
        LevelNumber = mazeSettings.levelNumber;

        IWinCondition winCondition;

        switch (mazeSettings.mazeWinCondition)
        {
        case WinConditionType.Boss:
            winCondition = gameObject.AddComponent <FindKey>();
            break;

        case WinConditionType.ClearLocation:
            winCondition = gameObject.AddComponent <ClearLocation>();
            break;

        case WinConditionType.CollectItems:
            winCondition = gameObject.AddComponent <CollectArtefacts>();
            break;

        default:
            throw new System.Exception("Can't generate maze without win condition");
        }

        winCondition.OnCompleted += WinConditionCompleted;

        MazeGenerator mazeGenerator = GetComponent <MazeGenerator>();

        PathfindingNode[]             nodes       = mazeGenerator.GenerateMaze(mazeSettings, winCondition, out int nodeCount);
        Pathfinding <PathfindingNode> pathfinding = new Pathfinding <PathfindingNode>(nodes, nodeCount);

        EnemyController.Pathfinder = pathfinding;

        _winConditionMessages = winCondition.GetMessages();
        return(_winConditionMessages[0]);
    }
コード例 #7
0
    // Vytvoří buňky a propojí je podle informací z Maze Settings
    public CellData GenerateCells(MazeSettingsSO mazeSettings, Vector3 startPoint)
    {
        _mazeSettings = mazeSettings;

        int cellCounter = 1;

        // Z, X
        _cells     = new Cell[_mazeSettings.length, _mazeSettings.width];
        _cellStack = new Stack <Vector2Int>();
        _xDistance = new int[_mazeSettings.width + 1];
        _zDistance = new int[_mazeSettings.length + 1];

        _zDistance[0] = _xDistance[0] = 0;

        // Náhodně rozhodne o délce buňek
        for (int i = 1; i < _mazeSettings.length + 1; i++)
        {
            if (_mazeSettings.randomDistanceBetweenCells)
            {
                _zDistance[i] = _zDistance[i - 1] + Random.Range(_mazeSettings.minDistanceMultiplyer, _mazeSettings.maxDistanceMultiplyer);
            }
            else
            {
                _zDistance[i] = i;
            }
        }

        // Náhodně rozhodne o výšce buňek
        for (int i = 1; i < _mazeSettings.width + 1; i++)
        {
            if (_mazeSettings.randomDistanceBetweenCells)
            {
                _xDistance[i] = _xDistance[i - 1] + Random.Range(_mazeSettings.minDistanceMultiplyer, _mazeSettings.maxDistanceMultiplyer);
            }
            else
            {
                _xDistance[i] = i;
            }
        }

        // První buňka - přídá všechny sousedy do zásobníku, Z, X
        Vector2Int firstCell = new Vector2Int(Random.Range(1, _mazeSettings.length - 1), Random.Range(1, _mazeSettings.width - 1));
        Vector2Int currentCellPositionInArray = firstCell;

        _cells[currentCellPositionInArray.x, currentCellPositionInArray.y] = new Cell(true, true, true, true);
        PushNeighbouringCells(currentCellPositionInArray);
        int maxNodeCount = (_zDistance[currentCellPositionInArray.x + 1] - _zDistance[currentCellPositionInArray.x]) * (_xDistance[currentCellPositionInArray.y + 1] - _xDistance[currentCellPositionInArray.y]);

        // Nové buňky se vytváří dokud zásobník není prázdný
        while (_cellStack.Count > 0)
        {
            currentCellPositionInArray = _cellStack.Pop();
            if (_cells[currentCellPositionInArray.x, currentCellPositionInArray.y] != null)
            {
                continue;
            }
            CreateNewCell(currentCellPositionInArray);
            CreateNewDoors(currentCellPositionInArray);
            PushNeighbouringCells(currentCellPositionInArray);
            cellCounter++;
            maxNodeCount += (_zDistance[currentCellPositionInArray.x + 1] - _zDistance[currentCellPositionInArray.x]) * (_xDistance[currentCellPositionInArray.y + 1] - _xDistance[currentCellPositionInArray.y]);
        }

        // Vrátí vytvořené buňky a s nimi nutné informace o nich
        return(new CellData(_cells, firstCell, cellCounter, maxNodeCount, _xDistance, _zDistance));
    }