// Vytvoří instanci části místnosti na mapě podle poču otevřených zdí private void SpawnTilePrefab(Subcell subcell) { int firstDoor = subcell.GetFirstDoor(); switch (subcell.GetDoorCount()) { case 1: Instantiate(_tileSets[subcell.TileType].tiles[0], subcell.Position, Quaternion.Euler(new Vector3(0, firstDoor * 90, 0)), transform); break; case 2: if (subcell.Neighbours[((firstDoor + 2) * 2) % 8] == null) { Instantiate(_tileSets[subcell.TileType].tiles[1], subcell.Position, Quaternion.Euler(new Vector3(0, firstDoor * 90, 0)), transform); } else { Instantiate(_tileSets[subcell.TileType].tiles[2], subcell.Position, Quaternion.Euler(new Vector3(0, firstDoor * 90, 0)), transform); } break; case 3: Instantiate(_tileSets[subcell.TileType].tiles[3], subcell.Position, Quaternion.Euler(new Vector3(0, (firstDoor - 1) * 90, 0)), transform); break; case 4: Instantiate(_tileSets[subcell.TileType].tiles[4], subcell.Position, Quaternion.identity, transform); break; default: throw new System.Exception("Cell can't have more than four doors"); } }
public Subcell(int position, float x, float y, float z, int tileType) { PositionInArray = position; Position = new Vector3(x, y, z); Neighbours = new Subcell[8]; TileType = tileType; NodesCreated = false; }
// Připojí vedlejší místnost private Subcell CreateOuterRoomSubcell(int subcellPositionInArray, int side) { Subcell currentSubcell = _subcellData.Subcells[subcellPositionInArray]; Subcell newSubcell; switch (side) { case 0: // TOP while (currentSubcell.Neighbours[0] != null) { currentSubcell = currentSubcell.Neighbours[0]; } newSubcell = new Subcell(_subcellData.EmptySpotInArray, currentSubcell.Position.x, currentSubcell.Position.y, currentSubcell.Position.z + _mazeSettings.distanceBetweenCells, currentSubcell.TileType); currentSubcell.ConnectToSubcell(newSubcell, Side.Top); break; case 1: // RIGHT while (currentSubcell.Neighbours[2] != null) { currentSubcell = currentSubcell.Neighbours[2]; } newSubcell = new Subcell(_subcellData.EmptySpotInArray, currentSubcell.Position.x + _mazeSettings.distanceBetweenCells, currentSubcell.Position.y, currentSubcell.Position.z, currentSubcell.TileType); currentSubcell.ConnectToSubcell(newSubcell, Side.Right); break; case 2: // BOTTOM while (currentSubcell.Neighbours[4] != null) { currentSubcell = currentSubcell.Neighbours[4]; } newSubcell = new Subcell(_subcellData.EmptySpotInArray, currentSubcell.Position.x, currentSubcell.Position.y, currentSubcell.Position.z - _mazeSettings.distanceBetweenCells, currentSubcell.TileType); currentSubcell.ConnectToSubcell(newSubcell, Side.Bottom); break; case 3: // LEFT while (currentSubcell.Neighbours[6] != null) { currentSubcell = currentSubcell.Neighbours[6]; } newSubcell = new Subcell(_subcellData.EmptySpotInArray, currentSubcell.Position.x - _mazeSettings.distanceBetweenCells, currentSubcell.Position.y, currentSubcell.Position.z, currentSubcell.TileType); currentSubcell.ConnectToSubcell(newSubcell, Side.Left); break; default: throw new System.Exception("Index out of bounds"); } _subcellData.Subcells[_subcellData.EmptySpotInArray] = newSubcell; _subcellData.EmptySpotInArray++; return(newSubcell); }
// Vytvoří místnost private void CreateRoom(Vector2Int position) { int tileType = _mazeSettings.roomTileTypes[Random.Range(0, _mazeSettings.roomTileTypes.Length)]; Vector2Int dimensions = _cellData.GetDimensions(position); // X, Z Vector2 realPosition = new Vector2(_startPoint.x + _cellData.XDistance[position.y] * _mazeSettings.distanceBetweenCells, _startPoint.z + _cellData.ZDistance[position.x] * _mazeSettings.distanceBetweenCells); // RLpos _cellData.Cells[position.x, position.y].lowestSubcellIndex = _emptySpotInArray; // Začne v levém spodním rohu for (int i = 0; i < dimensions.x; i++) // Z { for (int j = 0; j < dimensions.y; j++) // X { _subcells[_emptySpotInArray] = new Subcell(_emptySpotInArray, realPosition.x + _mazeSettings.distanceBetweenCells * j, _startPoint.y, realPosition.y + _mazeSettings.distanceBetweenCells * i, tileType); // RLpos // Když je podbuňka aspoň ve druhém sloupci, je potřeba ji propojit s podbuňkou nalevo od ní; (Y) if (j > 0) { _subcells[_emptySpotInArray].ConnectToSubcell(_subcells[_emptySpotInArray - 1], Side.Left); } // Když je podbuňka aspoň ve druhé řadě, je potřeba ji propojit s podbuňkou pod ní; (X) if (i > 0) { _subcells[_emptySpotInArray].ConnectToSubcell(_subcells[_emptySpotInArray - dimensions.y], Side.Bottom); // Když je podbuňka aspoň ve druhém sloupci, je potřeba ji propojit s podbuňkou vlevo dole od ní; if (j > 0) { _subcells[_emptySpotInArray].ConnectToSubcell(_subcells[_emptySpotInArray - dimensions.y - 1], Side.BottomLeft); } // Když je podbuňka není v posledním sloupci, je potřeba ji propojit s podbuňkou vpravo dole od ní; if (j < dimensions.y - 1) { _subcells[_emptySpotInArray].ConnectToSubcell(_subcells[_emptySpotInArray - dimensions.y + 1], Side.BottomRight); } } _emptySpotInArray++; } } // Propojí podbuňky s podbuňkami z jiných buňek ConnectSubcellsFromDifferentCells(position, dimensions); }
// Vytvoří místnost na kraji mapy a prpojí ji ke zbytku private void CreateOuterRoom() { int side = Random.Range(0, 4); Vector2Int cellPosition = GetOuterCell(side); Vector2Int dimensions = _cellData.GetDimensions(cellPosition); Vector2Int path = _cellData.GetPath(cellPosition, dimensions); int currenSubcellIndex = _cellData.Cells[cellPosition.x, cellPosition.y].lowestSubcellIndex + (dimensions.y * path.x) + path.y; Subcell outerRoomSubcell = CreateOuterRoomSubcell(currenSubcellIndex, side); GetComponent <TileGenerator>().SpawnSingleTile(outerRoomSubcell.Position, outerRoomSubcell.GetFirstDoor() * 90, 2, outerRoomSubcell.TileType); GameObject boss = GetComponent <Spawner>().SpawnBossRoom(outerRoomSubcell.Position, side, _mazeSettings.distanceBetweenCells); boss.GetComponent <Boss>().OnBossDeath = _winCondition.OnCompleted; }
// Propojí navzájem podbuňku s druhou podbuňkou public void ConnectToSubcell(Subcell other, Side direction) { switch (direction) { case Side.Top: Neighbours[0] = other; other.Neighbours[4] = this; break; case Side.Right: Neighbours[2] = other; other.Neighbours[6] = this; break; case Side.Bottom: Neighbours[4] = other; other.Neighbours[0] = this; break; case Side.Left: Neighbours[6] = other; other.Neighbours[2] = this; break; case Side.TopRight: Neighbours[1] = other; other.Neighbours[5] = this; break; case Side.BottomRight: Neighbours[3] = other; other.Neighbours[7] = this; break; case Side.BottomLeft: Neighbours[5] = other; other.Neighbours[1] = this; break; case Side.TopLeft: Neighbours[7] = other; other.Neighbours[3] = this; break; } }
// Propojí uzly v podbuňce s uzly v sousedních buňkách private void ConnectNodesInSubcellToNeighbours(Subcell subcell, int dimension) { for (int i = 0; i < 8; i++) { // Přeskakuje diagonální propojení buňek - odstranit, kdyby to bylo potřeba if (i % 2 == 1) { continue; } if (subcell.Neighbours[i] != null) { if (subcell.Neighbours[i].NodesCreated) { ConnectNodesFromDifferentSubcells(subcell, subcell.Neighbours[i], i, dimension); } } } }
// Propojí vyhledávací uzly z dvou různých podbuňek private void ConnectNodesFromDifferentSubcells(Subcell first, Subcell second, int direction, int dimension) { switch (direction) { case 0: { int firstID = first.LowestPathfindingNodeID + (dimension) * (dimension - 1); int secondID = second.LowestPathfindingNodeID; for (int i = 0; i < dimension; i++) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID], Side.Top); if (i < dimension - 1) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID + 1], Side.TopRight); } if (i > 0) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID - 1], Side.TopLeft); } firstID++; secondID++; } break; } case 1: ConnectTwoNodes(_pathfindingNodes[first.LowestPathfindingNodeID + (dimension * dimension) - 1], _pathfindingNodes[second.LowestPathfindingNodeID], Side.TopRight); break; case 2: { int firstID = first.LowestPathfindingNodeID + dimension - 1; int secondID = second.LowestPathfindingNodeID; for (int i = 0; i < dimension; i++) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID], Side.Right); if (i < dimension - 1) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID + dimension], Side.TopRight); } if (i > 0) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID - dimension], Side.BottomRight); } firstID += dimension; secondID += dimension; } break; } case 3: ConnectTwoNodes(_pathfindingNodes[first.LowestPathfindingNodeID + (dimension - 1)], _pathfindingNodes[second.LowestPathfindingNodeID + (dimension) * (dimension - 1)], Side.BottomRight); break; case 4: { int firstID = first.LowestPathfindingNodeID; int secondID = second.LowestPathfindingNodeID + (dimension) * (dimension - 1); for (int i = 0; i < dimension; i++) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID], Side.Bottom); if (i < dimension - 1) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID + 1], Side.BottomRight); } if (i > 0) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID - 1], Side.BottomLeft); } firstID++; secondID++; } break; } case 5: ConnectTwoNodes(_pathfindingNodes[first.LowestPathfindingNodeID], _pathfindingNodes[second.LowestPathfindingNodeID + (dimension * dimension) - 1], Side.BottomLeft); break; case 6: { int firstID = first.LowestPathfindingNodeID; int secondID = second.LowestPathfindingNodeID + dimension - 1; for (int i = 0; i < dimension; i++) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID], Side.Left); if (i < dimension - 1) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID + dimension], Side.TopLeft); } if (i > 0) { ConnectTwoNodes(_pathfindingNodes[firstID], _pathfindingNodes[secondID - dimension], Side.BottomLeft); } firstID += dimension; secondID += dimension; } break; } case 7: ConnectTwoNodes(_pathfindingNodes[first.LowestPathfindingNodeID + (dimension) * (dimension - 1)], _pathfindingNodes[second.LowestPathfindingNodeID + (dimension - 1)], Side.TopLeft); break; } }
// Vytvoří chodbu private void CreateCorridor(Vector2Int position) { int tileType = _mazeSettings.corridorTileTypes[Random.Range(0, _mazeSettings.corridorTileTypes.Length)]; // X, Z Vector2 realPosition = new Vector2(_startPoint.x + _cellData.XDistance[position.y] * _mazeSettings.distanceBetweenCells, _startPoint.z + _cellData.ZDistance[position.x] * _mazeSettings.distanceBetweenCells); // RLpos Vector2Int dimensions = _cellData.GetDimensions(position); Vector2Int pathCoords = _cellData.GetPath(position, dimensions); Vector2 centerPosition = new Vector2(realPosition.x + _mazeSettings.distanceBetweenCells * pathCoords.y, realPosition.y + _mazeSettings.distanceBetweenCells * pathCoords.x); // RLpos // Vytvoří podbuňku uprostřed buňky; Z, X int centerPositionInArray = _emptySpotInArray + (dimensions.y * pathCoords.x) + pathCoords.y; _cellData.Cells[position.x, position.y].lowestSubcellIndex = _emptySpotInArray; Subcell centerSubcell = new Subcell(centerPositionInArray, centerPosition.x, _startPoint.y, centerPosition.y, tileType); _subcells[centerPositionInArray] = centerSubcell; // Vytváří podbuňky nad sebou až k hranici buňky; Top if (_cellData.Cells[position.x, position.y].IsDoor(Side.Top)) { if (pathCoords.x < (dimensions.x - 1)) { int positionInArray = centerPositionInArray + dimensions.y; _subcells[positionInArray] = new Subcell(centerPositionInArray + dimensions.y, centerPosition.x, _startPoint.y, centerPosition.y + _mazeSettings.distanceBetweenCells, tileType); // RLpos _subcells[positionInArray].ConnectToSubcell(centerSubcell, Side.Bottom); } } // Vytváří podbuňky od prostřední podbuňky napravo až k hranici buňky; Right if (_cellData.Cells[position.x, position.y].IsDoor(Side.Right)) { if (pathCoords.y < (dimensions.y - 1)) { int positionInArray = centerPositionInArray + 1; _subcells[positionInArray] = new Subcell(centerPositionInArray + 1, centerPosition.x + _mazeSettings.distanceBetweenCells, _startPoint.y, centerPosition.y, tileType); // RLpos _subcells[positionInArray].ConnectToSubcell(centerSubcell, Side.Left); } } // Vytváří podbuňky pod sebou až k hranici buňky; Bottom if (_cellData.Cells[position.x, position.y].IsDoor(Side.Bottom)) { if (pathCoords.x > 0) { int positionInArray = centerPositionInArray - dimensions.y; _subcells[positionInArray] = new Subcell(centerPositionInArray - dimensions.y, centerPosition.x, _startPoint.y, centerPosition.y - _mazeSettings.distanceBetweenCells, tileType); // RLpos _subcells[positionInArray].ConnectToSubcell(centerSubcell, Side.Top); } } // Vytváří podbuňky od prostřední podbuňky nalevo až k hranici buňky; Left if (_cellData.Cells[position.x, position.y].IsDoor(Side.Left)) { if (pathCoords.y > 0) { int positionInArray = centerPositionInArray - 1; _subcells[positionInArray] = new Subcell(centerPositionInArray - 1, centerPosition.x - _mazeSettings.distanceBetweenCells, _startPoint.y, centerPosition.y, tileType); // RLpos _subcells[positionInArray].ConnectToSubcell(centerSubcell, Side.Right); } } _emptySpotInArray += dimensions.x * dimensions.y; // Propojí podbuňky s podbuňkami ze sousedících buňek ConnectSubcellsFromDifferentCells(position, dimensions); }