Exemplo n.º 1
0
    // Generate a path between 2 rooms in a simple and direct way.
    private void GeneratePathBetweenRooms(Vec2i start, Vec2i end)
    {
        // Choose the directions towards the end room.
        Direction directionX = (end.x > start.x) ? Direction.EAST : Direction.WEST;
        Direction directionY = (end.y > start.y) ? Direction.NORTH : Direction.SOUTH;

        Vec2i current = start;
        Vec2i last    = current;

        while (current != end)
        {
            int axis = Random.Range(0, 2);
            if (axis == 0 && current.x == end.x)
            {
                axis = 1;
            }
            else if (axis == 1 && current.y == end.y)
            {
                axis = 0;
            }
            if (axis == 0)
            {
                // Take an X direction.
                current.x += (directionX == Direction.EAST) ? 1 : -1;
                // Connect the rooms.
                if (current.x >= 0 && current.x < width && current.y >= 0 && current.y < height)
                {
                    rooms[last.x, last.y].walls       |= (int)directionX;
                    rooms[current.x, current.y].walls |= (int)DirectionFuncs.GetOpposite(directionX);
                }
            }
            else
            {
                // Take the Y direction.
                current.y += (directionY == Direction.NORTH) ? 1 : -1;
                // Connect the rooms.
                if (current.x >= 0 && current.x < width && current.y >= 0 && current.y < height)
                {
                    rooms[last.x, last.y].walls       |= (int)directionY;
                    rooms[current.x, current.y].walls |= (int)DirectionFuncs.GetOpposite(directionY);
                }
            }
            if (current != end)
            {
                rooms[current.x, current.y].isPath = true;
                rooms[current.x, current.y].isNull = false;
            }
            last = current;
        }
    }
Exemplo n.º 2
0
    // Generate the maze using the Growing Tree algorithm.
    private void GenerateMaze()
    {
        int x = Random.Range(0, width);
        int y = Random.Range(0, height);

        List <Zone> cells = new List <Zone>();

        cells.Add(zones[x, y]);

        Direction[] directions = { Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST };

        while (cells.Count > 0)
        {
            int index = ChooseIndex(cells.Count);
            x = cells[index].x;
            y = cells[index].y;

            Utils.Shuffle <Direction>(directions);

            foreach (Direction direction in directions)
            {
                int newX = x + DirectionFuncs.GetX(direction);
                int newY = y + DirectionFuncs.GetY(direction);
                if (newX >= 0 && newX < width && newY >= 0 && newY < height && zones[newX, newY].walls == 0)
                {
                    zones[x, y].walls       |= (int)direction;
                    zones[newX, newY].walls |= (int)DirectionFuncs.GetOpposite(direction);
                    cells.Add(zones[newX, newY]);
                    index = -1;
                    break;
                }
            }
            if (index > -1)
            {
                cells.RemoveAt(index);
            }
        }
    }
Exemplo n.º 3
0
    // Generate filling rooms.
    private void GenerateFilling()
    {
        List <Room> fillingRooms = new List <Room>();

        // NOTE: If a room has walls == 15, it means that nothing can be added to the room.

        // In the first iteration exists a possibility of creating a filling room touching some of the path rooms.
        // Store the rooms in a list to continue iterating later.
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                if (rooms[i, j].isPath && rooms[i, j].walls < 15)   // 15 means that is not completely surrounded.
                {
                    for (Direction dir = Direction.NORTH; dir <= Direction.WEST; dir += (int)dir)
                    {
                        int x = i + DirectionFuncs.GetX(dir);
                        int y = j + DirectionFuncs.GetY(dir);
                        if (x >= 0 && x < width && y >= 0 && y < height)
                        {
                            if (rooms[x, y].isNull)
                            {
                                if (Random.value > 0.5f)
                                {
                                    rooms[x, y].filling = 1;
                                    rooms[x, y].isNull  = false;
                                    rooms[i, j].walls  |= (int)dir;
                                    rooms[x, y].walls  |= (int)DirectionFuncs.GetOpposite(dir);
                                    fillingRooms.Add(rooms[x, y]);
                                }
                            }
                        }
                    }
                }
            }
        }

        // IMPORTANT: This is similar to the Drunkard Walk algorithm (Random Walk).
        int iterations = Random.Range(0, 4);
        int filling    = 2;

        while (iterations > 0)
        {
            List <Room> nextFillingRooms = new List <Room>();
            for (int i = 0; i < fillingRooms.Count; i++)
            {
                if (fillingRooms[i].walls < 15)
                {
                    for (Direction dir = Direction.NORTH; dir <= Direction.WEST; dir += (int)dir)
                    {
                        int x = fillingRooms[i].x + DirectionFuncs.GetX(dir);
                        int y = fillingRooms[i].y + DirectionFuncs.GetY(dir);
                        if (x >= 0 && x < width && y >= 0 && y < height)
                        {
                            if (rooms[x, y].isNull)
                            {
                                if (Random.value > 0.5f)
                                {
                                    rooms[x, y].filling = filling;
                                    rooms[x, y].isNull  = false;
                                    rooms[fillingRooms[i].x, fillingRooms[i].y].walls |= (int)dir;
                                    rooms[x, y].walls |= (int)DirectionFuncs.GetOpposite(dir);
                                    nextFillingRooms.Add(rooms[x, y]);
                                }
                            }
                        }
                    }
                }
            }
            fillingRooms = nextFillingRooms;
            filling++;
            iterations--;
        }
    }
Exemplo n.º 4
0
    // Marks the zones that have keys and/or doors.
    private void CreateDoorsAndKeys(ref Zone zone, Direction from, ref int region, ref int order)
    {
        List <Direction> dirs = GetAvailableDirections(zone, from);

        if (dirs.Count == 0)
        {
            // Put a key.
            zone.key    = ++region;
            zone.region = region;
            zone.order  = ++order;
            order       = 0;
        }
        else
        {
            // Continue iterating.
            int lastRegion = region;
            foreach (Direction dir in dirs)
            {
                if (lastRegion != region && dirs.Count > 1)
                {
                    // Put a door.
                    lastRegion = region;
                    switch (dir)
                    {
                    case Direction.NORTH:
                        zone.northDoor = region;
                        break;

                    case Direction.EAST:
                        zone.eastDoor = region;
                        break;

                    case Direction.SOUTH:
                        zone.southDoor = region;
                        break;

                    case Direction.WEST:
                        zone.westDoor = region;
                        break;
                    }
                }

                if (zone.region == 0)
                {
                    zone.region = region + 1;
                    zone.order  = ++order;
                }
                CreateDoorsAndKeys(ref zones[zone.x + DirectionFuncs.GetX(dir), zone.y + DirectionFuncs.GetY(dir)], DirectionFuncs.GetOpposite(dir), ref region, ref order);
            }
        }
    }