Esempio n. 1
0
        /// <summary>
        /// Returns if the paths of the given moving walls overlap.
        /// This can only be true if the walls are parallel and in the same col/row.
        /// </summary>
        public static bool Overlap(MovingWall mw1, MovingWall mw2)
        {
            if (mw1.horizontal != mw2.horizontal)
            {
                return(false);
            }

            if (mw1.horizontal)
            {
                if (mw1.row != mw2.row)
                {
                    return(false);
                }

                return(mw1.col < mw2.col + mw2.distance + mw2.size - 1 &&
                       mw2.col < mw1.col + mw1.distance + mw1.size - 1);
            }
            else
            {
                if (mw1.col != mw2.col)
                {
                    return(false);
                }

                return(mw1.row < mw2.row + mw2.distance + mw2.size - 1 &&
                       mw2.row < mw1.row + mw1.distance + mw1.size - 1);
            }
        }
Esempio n. 2
0
        public void GenerateMaze(int width, int length)
        {
            // resetting grid.  Every tile has all walls
            ClearGameObjects();
            ResizeTiles(width, length);
            Tile tile = new Tile();

            tile.leftWall    = true;
            tile.upWall      = true;
            tile.rightWall   = true;
            tile.downWall    = true;
            tile.tempVisited = false;
            for (int c = 0; c < width; c++)
            {
                for (int r = 0; r < length; r++)
                {
                    tiles[c][r] = tile;
                }
            }

            // pick home base
            HomeBase = new Vector2Int(Random.Range(0, Width), Random.Range(0, Length));

            // generating maze with recursive backtracker algorithm - https://en.wikipedia.org/wiki/Maze_generation_algorithm
            Stack <Vector2Int> stack   = new Stack <Vector2Int>();
            Vector2Int         current = new Vector2Int(Random.Range(0, width), Random.Range(0, length));
            Tile temp = tiles [current.x] [current.y];

            temp.tempVisited            = true;
            tiles[current.x][current.y] = temp;
            int numVisited = 1;

            while (numVisited < NumTiles)
            {
                // choose random adjacent unvisited tile
                List <Vector2Int> unvisitedNeighbors = new List <Vector2Int> ();
                if (current.x > 0 && !tiles[current.x - 1][current.y].tempVisited)
                {
                    unvisitedNeighbors.Add(new Vector2Int(current.x - 1, current.y));
                }
                if (current.y > 0 && !tiles[current.x][current.y - 1].tempVisited)
                {
                    unvisitedNeighbors.Add(new Vector2Int(current.x, current.y - 1));
                }
                if (current.x < width - 1 && !tiles[current.x + 1][current.y].tempVisited)
                {
                    unvisitedNeighbors.Add(new Vector2Int(current.x + 1, current.y));
                }
                if (current.y < length - 1 && !tiles[current.x][current.y + 1].tempVisited)
                {
                    unvisitedNeighbors.Add(new Vector2Int(current.x, current.y + 1));
                }

                if (unvisitedNeighbors.Count > 0)
                {
                    // visit neighbor
                    Vector2Int next = unvisitedNeighbors[Random.Range(0, unvisitedNeighbors.Count)];
                    stack.Push(current);
                    // remove wall between tiles
                    Tile currentTile = tiles[current.x][current.y];
                    Tile nextTile    = tiles[next.x][next.y];
                    if (next.x > current.x)
                    {
                        currentTile.rightWall = false;
                        nextTile.leftWall     = false;
                    }
                    else if (next.y > current.y)
                    {
                        currentTile.upWall = false;
                        nextTile.downWall  = false;
                    }
                    else if (next.x < current.x)
                    {
                        currentTile.leftWall = false;
                        nextTile.rightWall   = false;
                    }
                    else
                    {
                        currentTile.downWall = false;
                        nextTile.upWall      = false;
                    }
                    nextTile.tempVisited = true;
                    numVisited++;
                    tiles[current.x][current.y] = currentTile;
                    tiles[next.x][next.y]       = nextTile;
                    current = next;
                }
                else
                {
                    // backtrack if no unvisited neighboring tiles
                    if (stack.Count > 0)
                    {
                        current = stack.Pop();
                    }
                }
            }

            // make moving walls and clear walls that would be in the way
            int loopCount = 0;

            for (int i = 0; i < numMovingWalls; i++)
            {
                // break if can't find enough space for moving walls
                loopCount++;
                if (loopCount > 9999)
                {
                    break;
                }

                MovingWall movingWall = Instantiate(movingWallPrefab, transform).GetComponent <MovingWall>();
                movingWall.horizontal = true;                //Random.value < .5f;

                if (movingWall.horizontal)
                {
                    movingWall.size = Mathf.Min(movingWallSize, width - movingWallDistanceMin);
                }
                else
                {
                    movingWall.size = Mathf.Min(movingWallSize, length - movingWallDistanceMin);
                }

                if (movingWall.horizontal)
                {
                    movingWall.distance = Random.Range(Mathf.Min(movingWallDistanceMin, width - movingWall.size + 1), Mathf.Min(movingWallDistanceMax, width - movingWall.size + 1) + 1);
                    movingWall.col      = Random.Range(0, width - movingWall.distance + 1 - movingWall.size + 1);
                    movingWall.row      = Random.Range(1, length);
                }
                else
                {
                    movingWall.distance = Random.Range(Mathf.Min(movingWallDistanceMin, length - movingWall.size + 1), Mathf.Min(movingWallDistanceMax, length - movingWall.size + 1) + 1);
                    movingWall.col      = Random.Range(1, width);
                    movingWall.row      = Random.Range(0, length - movingWall.distance + 1 - movingWall.size + 1);
                }
                movingWall.speed = Random.Range(movingWallSpeedMin, movingWallSpeedMax);

                // check that wall doesn't overlap with other walls (can intersect though)
                bool overlaps = false;
                foreach (MovingWall other in movingWalls)
                {
                    if (MovingWall.Overlap(other, movingWall))
                    {
                        overlaps = true;
                        break;
                    }
                }
                if (overlaps)
                {
                    Destroy(movingWall.gameObject);
                    i--;
                    continue;
                }

                movingWall.SetRandomIndex();
                movingWall.RemoveWallsInPath();
                movingWall.UpdateTransform();

                movingWalls.Add(movingWall);
            }
            numMovingWalls = movingWalls.Count;



            // remove vertical strips of walls
            if (openStripsWidth + mazeStripsWidth > 0)
            {
                int offset = 0;                 // (aligns with border width)
                for (; offset < width; offset += openStripsWidth + mazeStripsWidth)
                {
                    for (int c = offset; c < Mathf.Min(offset + openStripsWidth, width); c++)
                    {
                        for (int r = 0; r < length; r++)
                        {
                            if (r > 0)
                            {
                                SetDownWall(c, r, false);
                            }
                            if (c > offset)
                            {
                                SetLeftWall(c, r, false);
                            }
                        }
                    }
                }
            }

            // remove walls at left vertical border
            for (int c = 0; c < Mathf.Min(openStripsWidth, width); c++)
            {
                for (int r = 0; r < length; r++)
                {
                    if (r > 0)
                    {
                        SetDownWall(c, r, false);
                    }
                    if (c > 0)
                    {
                        SetLeftWall(c, r, false);
                    }
                }
            }
            // remove walls at right vertical border
            for (int c = Mathf.Max(width - openStripsWidth, 0); c < width; c++)
            {
                for (int r = 0; r < length; r++)
                {
                    if (r > 0)
                    {
                        SetDownWall(c, r, false);
                    }
                    if (c > 0)
                    {
                        SetLeftWall(c, r, false);
                    }
                }
            }

            // remove walls at bottom horizontal border
            for (int r = 0; r < Mathf.Min(openStripsWidth, length); r++)
            {
                for (int c = 0; c < width; c++)
                {
                    if (r > 0)
                    {
                        SetDownWall(c, r, false);
                    }
                    if (c > 0)
                    {
                        SetLeftWall(c, r, false);
                    }
                }
            }
            // remove walls at top horizontal border
            for (int r = Mathf.Max(length - openStripsWidth, 0); r < length; r++)
            {
                for (int c = 0; c < width; c++)
                {
                    if (r > 0)
                    {
                        SetDownWall(c, r, false);
                    }
                    if (c > 0)
                    {
                        SetLeftWall(c, r, false);
                    }
                }
            }



            // instantiate gameObjects

            GameObject groundTile = Instantiate(tilePrefab, transform);

            groundTile.transform.localPosition = new Vector3(TILE_SPACING * (width - 1) / 2, groundTile.transform.localPosition.y - .01f, TILE_SPACING * (length - 1) / 2);
            groundTile.transform.localScale    = new Vector3(TILE_SPACING * width, groundTile.transform.localScale.y, TILE_SPACING * length);
            tileGameObjects.Add(groundTile);


            for (int c = 0; c < width; c++)
            {
                for (int r = 0; r < length; r++)
                {
                    tile = tiles[c][r];

                    // add tile, but only if it's home base
                    if (c == HomeBase.x && r == HomeBase.y)
                    {
                        GameObject tileGO = Instantiate(tilePrefab, transform);
                        tileGO.transform.localPosition = new Vector3(TILE_SPACING * c, tileGO.transform.localPosition.y, TILE_SPACING * r);
                        tileGameObjects.Add(tileGO);

                        tileGO.GetComponent <ZombieMaze.Tile>().IsHomeBase = true;
                    }


                    GameObject wallGO;
                    if (tile.leftWall)
                    {
                        wallGO = Instantiate(wallPrefab, transform);
                        wallGO.transform.localPosition = new Vector3(
                            TILE_SPACING * (c - .5f),
                            wallGO.transform.localPosition.y,
                            TILE_SPACING * r
                            );
                        wallGO.transform.localRotation = Quaternion.Euler(0, 90, 0);
                        wallGameObjects.Add(wallGO);
                    }
                    if (tile.downWall)
                    {
                        wallGO = Instantiate(wallPrefab, transform);
                        wallGO.transform.localPosition = new Vector3(
                            TILE_SPACING * c,
                            wallGO.transform.localPosition.y,
                            TILE_SPACING * (r - .5f)
                            );
                        wallGO.transform.localRotation = Quaternion.Euler(0, 0, 0);
                        wallGameObjects.Add(wallGO);
                    }
                    if (c == width - 1 && tile.rightWall)
                    {
                        wallGO = Instantiate(wallPrefab, transform);
                        wallGO.transform.localPosition = new Vector3(
                            TILE_SPACING * (c + .5f),
                            wallGO.transform.localPosition.y,
                            TILE_SPACING * r
                            );
                        wallGO.transform.localRotation = Quaternion.Euler(0, 90, 0);
                        wallGameObjects.Add(wallGO);
                    }
                    if (r == length - 1 && tile.upWall)
                    {
                        wallGO = Instantiate(wallPrefab, transform);
                        wallGO.transform.localPosition = new Vector3(
                            TILE_SPACING * c,
                            wallGO.transform.localPosition.y,
                            TILE_SPACING * (r + .5f)
                            );
                        wallGO.transform.localRotation = Quaternion.Euler(0, 0, 0);
                        wallGameObjects.Add(wallGO);
                    }
                }
            }

            CreateCapsules(numCapsules);

            CreateZombies(numZombies);


            Camera.main.GetComponent <CameraControl>().InitialSetUp();
        }