示例#1
0
    private void GenerateChambers(int count)
    {
        // Create an array of chamber placements to decide.
        ChamberPlacement[] chamberPlacements = new ChamberPlacement[count + GENERATION_LOOK_AHEAD];

        // Figure out placement for every chamber to create.
        bool hitConflict = false;

        for (int i = 0; i < chamberPlacements.Length; i++)
        {
            // Obtain the appropriate chamber prefab.
            Chamber chamberPrefab = null;
            if (i == 0 && _placedChambers.Count == 0)
            {
                // If we have not created any chambers yet, this chamber will need to be a starting chamber.
                chamberPrefab = GetRandomChamber(ChamberType.StartingCap);
            }
            else if (hitConflict)
            {
                // If we hit a conflict, we'll allow for any chamber here to minimize the chances.
                chamberPrefab = GetRandomChamber(ChamberType.Tunnel);
            }
            else
            {
                // Obtain our count of consecutive straight chambers beforehand.
                int straightCount = GetStraightChamberCount(chamberPlacements, i);

                // Obtain our chamber direction, making sure we hit the minimum amount of straights.
                ChamberDirection targetDirection = ChamberDirection.Straight;
                if (straightCount >= _minimumConsecutiveStraightChambers)
                {
                    targetDirection = GetRandomChamberDirection();
                }

                // Obtain our chamber with the given direction.
                chamberPrefab = GetRandomChamberWithDirection(targetDirection);
            }

            // Determine the positioning of our next chamber.
            Direction targetEntranceDirection = Direction.Left;
            Vector2   targetEntrancePoint     = Vector2.zero;
            if (i > 0)
            {
                // We have determined placements in this run already, so look at the previous placement.
                ChamberPlacement lastChamberPlacement = chamberPlacements[i - 1];
                targetEntranceDirection = lastChamberPlacement.ExitDirection.Inverse();
                targetEntrancePoint     = lastChamberPlacement.ExitPoint;
            }
            else if (_placedChambers.Count > 0)
            {
                // We have no placements in this run, look to the spawned chambers.
                ChamberPlacement lastChamberPlacement = _placedChambers[_placedChambers.Count - 1];
                targetEntranceDirection = lastChamberPlacement.ExitDirection.Inverse();
                targetEntrancePoint     = lastChamberPlacement.ExitPoint;
            }
            else
            {
                // It's our first chamber, find a random orientation to simulate entry from.
                targetEntranceDirection = (Direction)_chamberRNG.Range(0, 2);
            }


            // Create our corresponding chamber placement to create and verify the validity of placements.
            chamberPlacements[i] = new ChamberPlacement(_chamberRNG, chamberPrefab, targetEntranceDirection);
            chamberPlacements[i].SetEntrancePoint(targetEntrancePoint);

            // Loop backward through the chamber placements to check for overlaps (skip immediate previous one since it will touch)
            bool   overlapped = false;
            Bounds boundsA    = chamberPlacements[i].Bounds;
            for (int x = i - 2; x >= 0; x--)
            {
                Bounds boundsB = chamberPlacements[x].Bounds;
                if (boundsA.Intersects(boundsB))
                {
                    // There was an overlap with chamberPlacement[i] and chamberPlacement[x], we'll want to regenerate.
                    i           = x - 1;
                    overlapped  = true;
                    hitConflict = true;
                    break;
                }
            }
            // If we overlapped already, we'll want to start our iteration from the new point we set.
            if (overlapped)
            {
                continue;
            }

            // Now we'll want to loop backwards through spawned chambers, and check for overlaps as well.
            overlapped = false;
            // Define the last chamber to start from, if we're generating our first placement, we'll want to skip the last spawned chamber since it will touch it.
            int lastChamber = (i == 0) ? _placedChambers.Count - 2 : _placedChambers.Count - 1;
            for (int x = lastChamber; x >= 0; x--)
            {
                Bounds boundsB = _placedChambers[x].Bounds;
                if (boundsA.Intersects(boundsB))
                {
                    // There was an overlap with chamberPlacement[i] and chamberPlacement[x], we'll want to regenerate.
                    i           = -1;
                    overlapped  = true;
                    hitConflict = true;
                    break;
                }
            }
            // If we overlapped already, we'll want to start our iteration from the new point we set.
            if (overlapped)
            {
                continue;
            }

            // Reset our conflict flag.
            hitConflict = false;
        }

        // Spawn all of the placed chambers.
        SpawnChambers(chamberPlacements, 0, count);
    }
示例#2
0
    private Chamber GetRandomChamberWithDirection(ChamberDirection chamberDirection)
    {
        int randomIndex = _chamberRNG.Range(0, _continuousChambersByDirection[chamberDirection].Count);

        return(_continuousChambersByDirection[chamberDirection].ElementAt(randomIndex));
    }