Beispiel #1
0
    private static bool OutOfBounds(IntVector roomIndex, MapController.Map map)
    {
        int x = roomIndex.x;
        int y = roomIndex.y;

        return(x < 0 || y < 0 || x >= map.size.x || y >= map.size.y);
    }
Beispiel #2
0
    public void Generate(MapController.Map map)
    {
        rt.sizeDelta        = new Vector2(map.size.x * roomSize, map.size.y * roomSize);
        rt.anchoredPosition = Vector3.zero;
        rt.pivot            = new Vector2(.5f, .5f);
        Vector2 shiftVector = new Vector2((-rt.sizeDelta.x + roomSize) / 2, (rt.sizeDelta.y - roomSize) / 2);

        rt.localScale = new Vector3(Mathf.Min(1, 4.0f / map.size.x), Mathf.Min(1, 4.0f / map.size.y), 1);

        for (int i = transform.childCount - 1; i >= 0; i--)
        {
            Destroy(transform.GetChild(i));
        }

        rooms = new GameObject[map.size.x][];
        for (int i = 0; i < map.size.x; i++)
        {
            rooms[i] = new GameObject[map.size.y];
            for (int j = 0; j < map.size.y; j++)
            {
                if (map.rooms[i][j].active)
                {
                    rooms[i][j] = (GameObject)Instantiate(room);
                    rooms[i][j].transform.SetParent(transform);
                    rooms[i][j].transform.localPosition = new Vector2(i * 80, -j * 80) + shiftVector;
                    rooms[i][j].transform.localScale    = new Vector2(1, 1);

                    if (!map.rooms[i][j].up)
                    {
                        Destroy(rooms[i][j].transform.Find("Up Door").gameObject);
                    }
                    if (!map.rooms[i][j].down)
                    {
                        Destroy(rooms[i][j].transform.Find("Down Door").gameObject);
                    }
                    if (!map.rooms[i][j].left)
                    {
                        Destroy(rooms[i][j].transform.Find("Left Door").gameObject);
                    }
                    if (!map.rooms[i][j].right)
                    {
                        Destroy(rooms[i][j].transform.Find("Right Door").gameObject);
                    }

                    int    index = j + map.size.y * i;
                    Button b     = rooms[i][j].GetComponent <Button>();
                    b.onClick.AddListener(() =>
                    {
                        ((MapController)MapController.Instance).SetRoom(index);
                    }
                                          );
                    rooms[i][j].SetActive(map.start.Equals(new IntVector(i, j)));
                }
                if (map.end.Equals(new IntVector(i, j)))
                {
                    endMarker = (GameObject)Instantiate(endpointPrefab);
                    endMarker.transform.SetParent(transform);
                    endMarker.transform.localPosition = rooms[i][j].transform.localPosition;
                    endMarker.transform.localScale    = new Vector3(1, 1, 1);
                }
            }
        }
        playerMarker = (GameObject)Instantiate(playerLocPrefab);
        playerMarker.transform.SetParent(transform);
        playerMarker.transform.localPosition = rooms[map.start.x][map.start.y].transform.localPosition;
        playerMarker.transform.localScale    = new Vector3(1, 1, 1);
    }
Beispiel #3
0
    public static MapController.Map RandomMap(int width, int height, int difficulty, float loadFactor)
    {
        MapController.Map map = new MapController.Map();
        map.difficulty = difficulty;
        map.size       = new IntVector(width, height);

        map.rooms = new MapController.Room[width][];
        for (int i = 0; i < width; i++)
        {
            map.rooms[i] = new MapController.Room[height];
        }

        int roomCount = 1; //generation starting room

        IntVector genStart = new IntVector(Random.Range(0, width), Random.Range(0, height));

        map.rooms[genStart.x][genStart.y] = RandomRoom(difficulty);

        Queue <IntVector> queue = new Queue <IntVector>();

        queue.Enqueue(genStart);
        // Debug.Log("Start generation at: (" + map.start.x + ", " + map.start.y + ")");

        while (queue.Count > 0)
        {
            if (1.0f * roomCount >= loadFactor * width * height)
            {
                break;
            }
            IntVector currentRoom = queue.Dequeue();
            int       x           = currentRoom.x;
            int       y           = currentRoom.y;

            int availableDirections = 0;
            for (int i = -1; i <= 1; i++)
            {
                for (int j = i * i - 1; j <= 1; j += 2)
                {
                    if (!OutOfBounds(new IntVector(x + i, y + j), map) && !map.rooms[x + i][y + j].active)
                    {
                        availableDirections++;
                    }
                }
            }
            float[] thresholds = new float[availableDirections];
            for (int i = 0; i < availableDirections; i++)
            {
                thresholds[i] = 1 - 0.25f * i;
            }

            // Randomly distribute thresholds among available directions
            for (int i = 0; i < availableDirections; i++)
            {
                float temp        = thresholds[i];
                int   randomIndex = Random.Range(i, availableDirections);
                thresholds[i]           = thresholds[randomIndex];
                thresholds[randomIndex] = temp;
            }
            int thresholdIndex = 0;

            // Loops through four directions (i, j)
            for (int i = -1; i <= 1; i++)
            {
                for (int j = i * i - 1; j <= 1; j += 2)
                {
                    if (OutOfBounds(new IntVector(x + i, y + j), map) || map.rooms[x + i][y + j].active)
                    {
                        continue;
                    }

                    // string dir = (i == 0) ? ((j == -1) ? "up" : "down") : ((i == -1) ? "left" : "right");
                    // Debug.Log(dir + " " + thresholds[thresholdIndex]);
                    if (Random.value > thresholds[thresholdIndex++])
                    {
                        continue;
                    }

                    // Debug.Log("got through");

                    bool intersect = false;

                    if (i == 0 && j == -1)
                    {
                        map.rooms[x][y].up = true;
                    }
                    else if (i == 0 && j == 1)
                    {
                        map.rooms[x][y].down = true;
                    }
                    else if (i == -1 && j == 0)
                    {
                        map.rooms[x][y].left = true;
                    }
                    else if (i == 1 && j == 0)
                    {
                        map.rooms[x][y].right = true;
                    }

                    int distance = WeightedDistance((j == 0) ? width : height);

                    // Check for edge at (x + i * distance, y + j * distance); if edge, shrink distance until inside the grid
                    for (int k = distance; k > 0; k--)
                    {
                        if (!OutOfBounds(new IntVector(x + i * k, y + j * k), map))
                        {
                            distance = k;
                            break;
                        }
                    }
                    // Debug.Log("distance: " + distance);
                    // Activate Corridors
                    for (int k = 1; k < distance; k++)
                    {
                        if (map.rooms[x + i * k][y + j * k].active)
                        {
                            intersect = true;
                        }
                        else
                        {
                            map.rooms[x + i * k][y + j * k] = RandomRoom(difficulty);
                            roomCount++;
                        }

                        if (i == 0)
                        {
                            map.rooms[x + i * k][y + j * k].up   = true;
                            map.rooms[x + i * k][y + j * k].down = true;
                        }
                        else
                        {
                            map.rooms[x + i * k][y + j * k].left  = true;
                            map.rooms[x + i * k][y + j * k].right = true;
                        }
                    }

                    // Activate endpoint and add to queue
                    if (map.rooms[x + i * distance][y + j * distance].active)
                    {
                        intersect = true;
                    }
                    else
                    {
                        map.rooms[x + i * distance][y + j * distance] = RandomRoom(difficulty);
                        roomCount++;
                    }

                    if (i == 0 && j == -1)
                    {
                        map.rooms[x + i * distance][y + j * distance].down = true;
                    }
                    else if (i == 0 && j == 1)
                    {
                        map.rooms[x + i * distance][y + j * distance].up = true;
                    }
                    else if (i == -1 && j == 0)
                    {
                        map.rooms[x + i * distance][y + j * distance].right = true;
                    }
                    else if (i == 1 && j == 0)
                    {
                        map.rooms[x + i * distance][y + j * distance].left = true;
                    }

                    if (!intersect)
                    {
                        IntVector endpoint = new IntVector(x + i * distance, y + j * distance);
                        // Debug.Log("Enqueuing: " + endpoint.ToString());
                        queue.Enqueue(endpoint);
                    }
                }
            }
        } // End while loop

        // Find start point
        queue.Clear();
        queue.Enqueue(genStart);
        List <IntVector> visited = new List <IntVector>();

        IntVector latest = null;

        while (queue.Count > 0)
        {
            IntVector latestRoom = queue.Dequeue();
            if (visited.Contains(latestRoom))
            {
                continue;
            }
            visited.Add(latestRoom);
            latest = latestRoom;

            int x = latestRoom.x;
            int y = latestRoom.y;

            if (map.rooms[x][y].up)
            {
                queue.Enqueue(new IntVector(x, y - 1));
            }
            if (map.rooms[x][y].down)
            {
                queue.Enqueue(new IntVector(x, y + 1));
            }
            if (map.rooms[x][y].left)
            {
                queue.Enqueue(new IntVector(x - 1, y));
            }
            if (map.rooms[x][y].right)
            {
                queue.Enqueue(new IntVector(x + 1, y));
            }
        }
        map.start = latest;
        // Debug.Log("Starts at " + map.start.ToString());

        // Find endpoint
        queue.Clear();
        visited.Clear();
        queue.Enqueue(map.start);

        while (queue.Count > 0)
        {
            IntVector latestRoom = queue.Dequeue();
            if (visited.Contains(latestRoom))
            {
                continue;
            }
            visited.Add(latestRoom);
            latest = latestRoom;

            int x = latestRoom.x;
            int y = latestRoom.y;

            if (map.rooms[x][y].up)
            {
                queue.Enqueue(new IntVector(x, y - 1));
            }
            if (map.rooms[x][y].down)
            {
                queue.Enqueue(new IntVector(x, y + 1));
            }
            if (map.rooms[x][y].left)
            {
                queue.Enqueue(new IntVector(x - 1, y));
            }
            if (map.rooms[x][y].right)
            {
                queue.Enqueue(new IntVector(x + 1, y));
            }
        }
        map.end = latest;
        // Debug.Log("Ends at " + map.end.ToString());

        // Debug.Log("Room count: " + roomCount);

        /* map preview
         * string mapgen = "";
         * for (int j = 0; j < height; j++)
         * {
         *  string str1 = "";
         *  string str2 = "";
         *  for (int i = 0; i < width; i++)
         *  {
         *      string strP = "O";
         *      if (map.start.Equals(new IntVector(i, j)))
         *          strP = "S";
         *      else if (map.end.Equals(new IntVector(i, j)))
         *          strP = "E";
         *      str1 = str1 + (map.rooms[i][j].active ? strP : " ") + (map.rooms[i][j].right ? "--" : "  ");
         *      str2 = str2 + (map.rooms[i][j].down ? "|" : " ") + "  ";
         *  }
         *  mapgen = mapgen + "\n" + str1 + "\n" + str2;
         * }
         * Debug.Log(mapgen);
         */

        return(map);
    }