예제 #1
0
        private void automaticSlideshowCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            if (automaticSlideshowCheckbox.Checked)
            {
                var id = ++slideshowTaskId;

                Task.Run(() =>
                {
                    for (var i = slideshowIndex; i < generatedLayouts.Count; i++)
                    {
                        if (slideshowTaskId != id || !automaticSlideshowCheckbox.Checked)
                        {
                            return;
                        }

                        var idToShow = i;

                        Invoke((Action)(() =>
                        {
                            slideshowIndex = idToShow;
                            UpdateSlideshowInfo();
                            layoutToDraw = generatedLayouts[idToShow];
                            mainPictureBox.Refresh();
                        }));

                        Thread.Sleep(3000);
                    }
                });
            }
        }
예제 #2
0
        /// <summary>
        /// Draws a given layout and returns a string with SVG data.
        /// </summary>
        /// <param name="layout">Layout that should be drawn</param>
        /// <param name="width">Width of the SVG</param>
        /// <param name="showRoomNames">Whether to show rooms names</param>
        /// <param name="fixedFontSize">What should be the font size of room names</param>
        /// <param name="forceSquare">Whether to force the output to have 1:1 aspect ration</param>
        /// <param name="flipY">Whether to flip ty Y axis</param>
        /// <returns></returns>
        public string DrawLayout(LayoutGrid2D <TNode> layout, int width, bool showRoomNames = true, int?fixedFontSize = null, bool forceSquare = false, bool flipY = false)
        {
            if (width <= 0)
            {
                throw new ArgumentException("Width must be greater than zero.", nameof(width));
            }

            var ratio  = GetWidthHeightRatio(layout);
            var height = forceSquare ? width : (int)(width / ratio);

            data.AppendLine($"<svg viewBox=\"0 0 {width} {height}\" xmlns=\"http://www.w3.org/2000/svg\">");

            this.width  = width;
            this.height = height;
            this.flipY  = flipY;

            DrawLayout(layout, width, height, showRoomNames, fixedFontSize, 0.1f);

            data.AppendLine("</svg>");

            var svgData = data.ToString();

            data.Clear();

            return(svgData);
        }
예제 #3
0
    /// <summary>
    /// Run the generator and export the result.
    /// </summary>
    public LayoutGrid2D <int> Run()
    {
        LayoutGrid2D <int> layout = null;

        var levelDescription = GetLevelDescription();
        var generator        = new GraphBasedGeneratorGrid2D <int>(levelDescription);
        var i = 0;

        while (i < maxAttemptsToGenerateLevel)
        {
            try
            {
                layout = generator.GenerateLayout();
                break;
            }
            catch
            {
                i++;
                if (i >= maxAttemptsToGenerateLevel)
                {
                    throw;
                }
            }
        }


        return(layout);
    }
예제 #4
0
        private void slideshowRightButton_Click(object sender, EventArgs e)
        {
            automaticSlideshowCheckbox.Checked = false;

            if (slideshowIndex != generatedLayouts.Count - 1)
            {
                layoutToDraw = generatedLayouts[++slideshowIndex];
                mainPictureBox.Refresh();
            }

            UpdateSlideshowInfo();
        }
예제 #5
0
        private float GetWidthHeightRatio(LayoutGrid2D <TNode> layout)
        {
            var polygons = layout.Rooms.Select(x => x.Outline + x.Position).ToList();
            var points   = polygons.SelectMany(x => x.GetPoints()).ToList();

            var minx = points.Min(x => x.X);
            var miny = points.Min(x => x.Y);
            var maxx = points.Max(x => x.X);
            var maxy = points.Max(x => x.Y);

            var ratio = (maxx - minx) / (float)(maxy - miny);

            return(ratio);
        }
예제 #6
0
        /// <summary>
        /// Entry point of the class. Draws a given layout to an output with given dimensions.
        /// </summary>
        /// <param name="layout">Layout do be drawn</param>
        /// <param name="width">Width of the output</param>
        /// <param name="height">Height of the output</param>
        /// <param name="withNames">Whether names should be displayed</param>
        /// <param name="fixedFontSize"></param>
        /// <param name="borderSize"></param>
        protected void DrawLayout(LayoutGrid2D <TNode> layout, int width, int height, bool withNames, int?fixedFontSize = null, float borderSize = 0.2f)
        {
            var polygons = layout.Rooms.Select(x => x.Outline + x.Position).ToList();
            var points   = polygons.SelectMany(x => x.GetPoints()).ToList();

            var minx = points.Min(x => x.X);
            var miny = points.Min(x => x.Y);
            var maxx = points.Max(x => x.X);
            var maxy = points.Max(x => x.Y);

            var scale  = GetScale(minx, miny, maxx, maxy, width, height, borderSize);
            var offset = GetOffset(minx, miny, maxx, maxy, width, height, scale);

            DrawLayout(layout, scale, offset, withNames, fixedFontSize);
        }
예제 #7
0
        /// <summary>
        /// Draws a given layout to an output using a given scale and offset.
        /// </summary>
        /// <remarks>
        /// All points are tranfosmer using the TransformPoint method.
        /// </remarks>
        /// <param name="layout">Layout do be drawn</param>
        /// <param name="scale">Scale factor</param>
        /// <param name="offset"></param>
        /// <param name="withNames">Whether names should be displayed</param>
        /// <param name="fixedFontSize"></param>
        protected void DrawLayout(LayoutGrid2D <TNode> layout, float scale, Vector2Int offset, bool withNames, int?fixedFontSize = null)
        {
            var polygons = layout.Rooms.Select(x => x.Outline + x.Position).ToList();
            var rooms    = layout.Rooms.ToList();
            var minWidth = layout.Rooms.Where(x => !x.IsCorridor).Select(x => x.Outline + x.Position).Min(x => x.BoundingRectangle.Width);

            // TODO: remove later
            for (var i = 0; i < rooms.Count; i++)
            {
                var room    = rooms[i];
                var outline = GetOutline(polygons[i], room.Doors?.ToList())
                              .Select(x => Tuple.Create(TransformPoint(x.Item1, scale, offset), x.Item2)).ToList();

                var transformedPoints = polygons[i].GetPoints().Select(point => TransformPoint(point, scale, offset)).ToList();

                if (transformedPoints.All(x => x == new Vector2Int(0, 0)))
                {
                    throw new InvalidOperationException("One of the polygons could not be drawn because the canvas size is too small.");
                }

                var polygon = new PolygonGrid2D(transformedPoints);
                DrawRoomBefore(polygon, outline, 2);
            }

            for (var i = 0; i < rooms.Count; i++)
            {
                var room    = rooms[i];
                var outline = GetOutline(polygons[i], room.Doors?.ToList())
                              .Select(x => Tuple.Create(TransformPoint(x.Item1, scale, offset), x.Item2)).ToList();

                var transformedPoints = polygons[i].GetPoints().Select(point => TransformPoint(point, scale, offset)).ToList();

                if (transformedPoints.All(x => x == new Vector2Int(0, 0)))
                {
                    throw new InvalidOperationException("One of the polygons could not be drawn because the canvas size is too small.");
                }

                var polygon = new PolygonGrid2D(transformedPoints);
                DrawRoom(polygon, outline, 2);

                if (withNames && !room.IsCorridor)
                {
                    DrawTextOntoPolygon(polygon, room.Room.ToString(), fixedFontSize ?? 2.5f * minWidth);
                }
            }
        }
예제 #8
0
    public static LayoutGrid2D <int> Generate(int numberOfRooms, int roomMinWidth, int roomMaxWidth, int roomMinHeight, int roomMaxHeight)
    {
        try
        {
            var layout = LayoutGrid2D <int> .LoadFromJson(@"c:\temp\layout1.json");

            return(layout);
        }
        catch
        {
            var levelGenerator = new LevelLayoutGenerator(numberOfRooms, roomMinWidth, roomMaxWidth, roomMinHeight, roomMaxHeight);
            var layout         = levelGenerator.Run();
            layout.SaveToJson(@"c:\temp\layout.json");

            return(layout);
        }
    }
예제 #9
0
        public override IEnumerator Process()
        {
            var levelDescription = Payload.LevelDescription;

            if (config.Timeout <= 0)
            {
                throw new ArgumentException($"{nameof(config.Timeout)} must be greater than 0", nameof(config.Timeout));
            }

            var rootGameObject = config.RootGameObject;

            // If the root game objects was not set in the config, we do the following:
            // 1. Check if there already exists a game objects with a name reserved for the generated level
            // 2. Otherwise, we create a new empty game object
            if (rootGameObject == null)
            {
                rootGameObject = GameObject.Find("Generated Level");

                if (rootGameObject == null)
                {
                    rootGameObject = new GameObject("Generated Level");
                }
            }

            // We delete all the children from the root game object - we do not want to combine levels from different runs of the algorithm
            foreach (var child in rootGameObject.transform.Cast <Transform>().ToList())
            {
                child.transform.parent = null;
                PostProcessUtils.Destroy(child.gameObject);
            }

            // The LevelDescription class must be converted to MapDescription
            var levelDescriptionGrid2D = levelDescription.GetLevelDescription();

            levelDescriptionGrid2D.MinimumRoomDistance            = 1;
            levelDescriptionGrid2D.RoomTemplateRepeatModeOverride = GeneratorUtils.GetRepeatMode(config.RepeatModeOverride);

            var configuration = new GraphBasedGeneratorConfiguration <RoomBase>()
            {
                EarlyStopIfTimeExceeded = TimeSpan.FromMilliseconds(config.Timeout),
            };

            // We create the instance of the dungeon generator and inject the correct Random instance
            var generator = new GraphBasedGeneratorGrid2D <RoomBase>(levelDescriptionGrid2D, configuration);

            generator.InjectRandomGenerator(Payload.Random);

            // Run the generator in a different class so that the computation is not blocking
            LayoutGrid2D <RoomBase> layout = null;
            var task = Task.Run(() => layout = generator.GenerateLayout());

            while (!task.IsCompleted)
            {
                yield return(null);
            }

            // Throw an exception when a timeout is reached
            // TODO: this should be our own exception and not a generic exception
            if (layout == null)
            {
                if (task.Exception != null)
                {
                    if (task.Exception.InnerException != null)
                    {
                        throw task.Exception.InnerException;
                    }

                    throw task.Exception;
                }
                else
                {
                    throw new TimeoutException();
                }
            }

            // Transform the level to its Unity representation
            var generatedLevel = GeneratorUtils.TransformLayout(layout, levelDescription, rootGameObject);

            var stats = new GeneratorStats()
            {
                Iterations = generator.IterationsCount,
                TimeTotal  = generator.TimeTotal,
            };

            Debug.Log($"Layout generated in {stats.TimeTotal / 1000f:F} seconds");
            Debug.Log($"{stats.Iterations} iterations needed, {stats.Iterations / (stats.TimeTotal / 1000d):0} iterations per second");

            ((IGraphBasedGeneratorPayload)Payload).GeneratedLevel = generatedLevel;
            Payload.GeneratorStats = stats;

            yield return(null);
        }
예제 #10
0
        /// <summary>
        /// Run the generator.
        /// </summary>
        private void Run()
        {
            cancellationTokenSource = new CancellationTokenSource();
            var ct = cancellationTokenSource.Token;

            task = Task.Run(() =>
            {
                try
                {
                    dumpFolder          = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString();
                    dumpCount           = 0;
                    var layoutGenerator = settings.LayoutGenerator;

                    if (layoutGenerator == null)
                    {
                        var defaultGenerator = new GraphBasedGeneratorGrid2D <int>(settings.LevelDescription);
                        defaultGenerator.InjectRandomGenerator(new Random(settings.RandomGeneratorSeed));
                        layoutGenerator = defaultGenerator;
                    }

                    // Set cancellation token
                    if (layoutGenerator is ICancellable cancellable)
                    {
                        cancellable.SetCancellationToken(ct);
                    }

                    infoStopwatch.Start();

                    // Register handler that shows generated layouts OnValid
                    layoutGenerator.OnValid += layout =>
                    {
                        if (!showFinalLayouts.Checked)
                        {
                            return;
                        }

                        lastEvent    = GeneratorEvent.OnValid;
                        layoutToDraw = layout;
                        mainPictureBox.BeginInvoke((Action)(() => mainPictureBox.Refresh()));
                        SleepWithFastCancellation((int)showFinalLayoutsTime.Value, ct);
                    };

                    // Register handler that shows generated layouts OnPartialValid
                    layoutGenerator.OnPartialValid += layout =>
                    {
                        if (!showPartialValidLayouts.Checked)
                        {
                            return;
                        }

                        lastEvent    = GeneratorEvent.OnPartialValid;
                        layoutToDraw = layout;
                        mainPictureBox.BeginInvoke((Action)(() => mainPictureBox.Refresh()));
                        SleepWithFastCancellation((int)showAcceptedLayoutsTime.Value, ct);
                    };

                    // Register handler that shows generated layouts OnPerturbed
                    layoutGenerator.OnPerturbed += layout =>
                    {
                        if (!showPerturbedLayouts.Checked)
                        {
                            return;
                        }

                        lastEvent    = GeneratorEvent.OnPerturbed;
                        layoutToDraw = layout;
                        mainPictureBox.BeginInvoke((Action)(() => mainPictureBox.Refresh()));
                        SleepWithFastCancellation((int)showPerturbedLayoutsTime.Value, ct);
                    };

                    // Register handler that counts iteration count
                    layoutGenerator.OnPerturbed += layout =>
                    {
                        lastEvent = GeneratorEvent.OnPerturbed;
                        iterationsCount++;
                        if (infoStopwatch.ElapsedMilliseconds >= 200)
                        {
                            BeginInvoke((Action)(UpdateInfoPanel));
                            infoStopwatch.Restart();
                        }
                    };

                    // Register handler that resets iteration count
                    layoutGenerator.OnValid += layout =>
                    {
                        lastEvent       = GeneratorEvent.OnValid;
                        iterationsCount = 0;
                        layoutsCount++;
                        BeginInvoke((Action)(UpdateInfoPanel));
                        infoStopwatch.Restart();
                    };

                    generatedLayouts = new List <LayoutGrid2D <int> >()
                    {
                    };

                    for (int i = 0; i < settings.NumberOfLayouts; i++)
                    {
                        generatedLayouts.Add(layoutGenerator.GenerateLayout());
                    }

                    isRunning = false;
                    BeginInvoke((Action)(UpdateInfoPanel));
                    BeginInvoke((Action)(OnFinished));
                }
                catch (Exception e)
                {
                    ShowExceptionAndClose(e);
                }
            }, ct);
        }
예제 #11
0
        /// <summary>
        /// Draws a given layout and saves it to a PNG file.
        /// </summary>
        /// <param name="layout">Layout to be drawn.</param>
        /// <param name="path">Path to the file.</param>
        /// <param name="options">Options. See <see cref="DungeonDrawerOptions"/>.</param>
        public void DrawLayoutAndSave(LayoutGrid2D <TRoom> layout, string path, DungeonDrawerOptions options)
        {
            var bitmap = DrawLayout(layout, options);

            bitmap.Save(path);
        }
예제 #12
0
    private bool GenerateItemsFromTemplate(int xoffset, int yoffset, LevelInfo[,] levelStructure, LayoutGrid2D <int> layout)
    {
        var levelTemplate = new Dictionary <(int h, int w), List <List <List <LevelInfoDto> > > >();

        var occupiedPoints = new List <AStar.Point>();
        var firstRoom      = layout.Rooms[0];
        var lastRoom       = layout.Rooms[layout.Rooms.Count - 1];

        var indent     = firstRoom.Transformation == Edgar.Geometry.TransformationGrid2D.Identity ? 1 : -1;
        var startPoint = levelStructure[xoffset + firstRoom.Position.X + 1, yoffset + firstRoom.Position.Y + indent];

        startPoint.TileType = TileType.Player;

        indent = lastRoom.Transformation == Edgar.Geometry.TransformationGrid2D.Identity ? 1 : -1;
        var endPoint = levelStructure[xoffset + lastRoom.Position.X + 1, yoffset + lastRoom.Position.Y + indent];

        endPoint.TileType = TileType.Exit;

        foreach (var room in layout.Rooms)
        {
            if (room == firstRoom || room == lastRoom || room.IsCorridor)
            {
                continue;
            }

            var roomHeight = room.Outline.BoundingRectangle.Height;
            var roomWidth  = room.Outline.BoundingRectangle.Width;
            if (!levelTemplate.ContainsKey((roomHeight, roomWidth)))
            {
                var folderName     = $@"RandomLevelParts\OrdinaryLevelParts\{roomHeight}_{roomWidth}";
                var roomsTemplates = ResourcesManagment.LoadLevelStructureFromFolderInDto(folderName);
                levelTemplate.Add((roomHeight, roomWidth), roomsTemplates);
            }

            var roomTemplate = levelTemplate[(roomHeight, roomWidth)].OrderBy(a => UnityEngine.Random.value).FirstOrDefault();
예제 #13
0
        public static GeneratedLevel TransformLayout(LayoutGrid2D <RoomBase> layout, LevelDescription levelDescription, GameObject rootGameObject)
        {
            // var layoutCenter = GetLayoutCenter(layout);
            var prefabToRoomTemplateMapping = levelDescription.GetPrefabToRoomTemplateMapping();
            var corridorToConnectionMapping = levelDescription.GetCorridorToConnectionMapping();

            // Prepare an object to hold instantiated room templates
            var roomTemplateInstancesRoot = new GameObject(GeneratorConstants.RoomsRootName);

            roomTemplateInstancesRoot.transform.parent = rootGameObject.transform;

            // Initialize rooms
            var layoutData  = new Dictionary <RoomBase, RoomInstance>();
            var layoutRooms = layout.Rooms.ToDictionary(x => x.Room, x => x);

            foreach (var layoutRoom in layoutRooms.Values)
            {
                var roomTemplatePrefab = prefabToRoomTemplateMapping.GetByValue(layoutRoom.RoomTemplate);

                // Instantiate room template
                var roomTemplateInstance = Object.Instantiate(roomTemplatePrefab);
                roomTemplateInstance.transform.SetParent(roomTemplateInstancesRoot.transform);
                roomTemplateInstance.name = $"{layoutRoom.Room.GetDisplayName()} - {roomTemplatePrefab.name}";

                // Compute correct room position
                var position = layoutRoom.Position.ToUnityIntVector3();
                roomTemplateInstance.transform.position = position;

                // Correct the position based on the grid
                // This is important when there is some cell spacing or when the level is isometric
                var tilemapsHolder = roomTemplateInstance.transform.Find(GeneratorConstants.TilemapsRootName).gameObject;
                if (tilemapsHolder != null)
                {
                    var grid = tilemapsHolder.GetComponent <Grid>();
                    roomTemplateInstance.transform.position = grid.CellToLocal(position);
                }

                // Compute outline polygon
                var polygon = new Polygon2D(layoutRoom.Outline + layoutRoom.Position);

                var connection   = layoutRoom.IsCorridor ? corridorToConnectionMapping[layoutRoom.Room] : null;
                var roomInstance = new RoomInstance(layoutRoom.Room, layoutRoom.IsCorridor, connection, roomTemplatePrefab, roomTemplateInstance, position, polygon);

                // Add room info to the GameObject
                var roomInfo = roomTemplateInstance.GetComponent <RoomInfo>();

                if (roomInfo != null)
                {
                    PostProcessUtils.Destroy(roomInfo);
                }

                roomInfo = roomTemplateInstance.AddComponent <RoomInfo>();
                roomInfo.RoomInstance = roomInstance;

                layoutData.Add(layoutRoom.Room, roomInstance);
            }

            foreach (var roomInstance in layoutData.Values)
            {
                roomInstance.SetDoors(TransformDoorInfo(layoutRooms[roomInstance.Room].Doors, layoutData));
            }

            // Add level info
            var levelInfo = rootGameObject.GetComponent <LevelInfo>();

            if (levelInfo != null)
            {
                PostProcessUtils.Destroy(levelInfo);
            }

            levelInfo = rootGameObject.AddComponent <LevelInfo>();
            levelInfo.RoomInstances = layoutData.Values.ToList();

            return(new GeneratedLevel(layoutData, layout, rootGameObject));
        }
예제 #14
0
        public void Run()
        {
            #region hidden

            var levelDescription = new BasicsExample().GetLevelDescription();

            #endregion

            //md In this tutorial, we will see how to save and load level descriptions and generated layouts.

            //md ## Level descriptions (JSON)
            //md To save a level description to a JSON file, we can call the [`SaveToJson()`][LevelDescriptionGrid2D.SaveToJson(String, Boolean)] method:

            levelDescription.SaveToJson("levelDescription.json");

            //md And to load a level description from a JSON file, we can use the [`LoadFromJson()`][LevelDescriptionGrid2D.LoadFromJson(String)] method:

            levelDescription = LevelDescriptionGrid2D <int> .LoadFromJson("levelDescription.json");

            //md By default, the JSON serializer is configured to preserve references to objects. That means that when it first encounters an object, it assigns a unique id to id and when it encounters the same object later, it only references that id and does not serialize the object itself. This is good for when we want load the level description back in C# later, but it may cause problems if we want to use the JSON outside C#. Therefore, it is possible to disable this feature:

            levelDescription.SaveToJson("levelDescription.json", preserveReferences: false);

            //md > **Note:**: API reference for the `LevelDescriptionGrid2D` class can be found [here][LevelDescriptionGrid2D].

            //md ## Layouts (JSON)

            #region hidden

            levelDescription = new BasicsExample().GetLevelDescription();
            var generator = new GraphBasedGeneratorGrid2D <int>(levelDescription);
            var layout    = generator.GenerateLayout();

            #endregion

            //md It is possible to save a generated layout to JSON and then load it back:

            layout.SaveToJson("layout.json");
            layout = LayoutGrid2D <int> .LoadFromJson("layout.json");

            //md And it is also possible to disable the `preserveReferences` feature:

            layout.SaveToJson("layout.json", preserveReferences: false);

            //md > **Note:**: API reference for the `LayoutGrid2D` class can be found [here][LayoutGrid2D].

            //md ## Layouts (PNG)

            #region hidden

            layout = generator.GenerateLayout();

            #endregion

            //md It is possible to save a generated layout as a PNG. To do that, we have to create an instance of the `DungeonDrawer` class:

            var dungeonDrawer = new DungeonDrawer <int>();

            //md Then we can save the layout as a PNG:

            dungeonDrawer.DrawLayoutAndSave(layout, "dungeon.png", new DungeonDrawerOptions()
            {
                Width  = 2000,
                Height = 2000,
            });

            //md The dungeon drawer produces images that can be seen in all the examples in this documentation. The API reference of the `DungeonDrawerOptions` class can be found [here][DungeonDrawerOptions].
        }
예제 #15
0
        /// <summary>
        /// Draws a given layout and returns a bitmap with the drawing.
        /// </summary>
        /// <param name="layout">Layout to be drawn.</param>
        /// <param name="options">Options. See <see cref="DungeonDrawerOptions"/>.</param>
        public Bitmap DrawLayout(LayoutGrid2D <TRoom> layout, DungeonDrawerOptions options)
        {
            var roomOutlines = layout.Rooms.Select(x => x.Outline + x.Position).ToList();
            var boundingBox  = DrawingUtils.GetBoundingBox(roomOutlines);

            var(width, height, scale) = DrawingUtils.GetSize(boundingBox, options.Width, options.Height, options.Scale, options.PaddingAbsolute, options.PaddingPercentage);
            var offset = DrawingUtils.GetOffset(boundingBox, width, height, scale);

            bitmap   = new Bitmap(width, height);
            graphics = Graphics.FromImage(bitmap);
            graphics.SmoothingMode = SmoothingMode.HighQuality;

            using (SolidBrush brush = new SolidBrush(options.BackgroundColor))
            {
                graphics.FillRectangle(brush, 0, 0, width, height);
            }

            outlinePen = new Pen(Color.FromArgb(50, 50, 50), 0.2f)
            {
                EndCap   = LineCap.Round,
                StartCap = LineCap.Round
            };

            shadePen = new Pen(Color.FromArgb(204, 206, 206), 1.3f)
            {
                EndCap   = LineCap.Round,
                StartCap = LineCap.Round
            };

            var rooms = layout.Rooms.ToList();

            graphics.TranslateTransform(offset.X, offset.Y);
            graphics.ScaleTransform(scale, scale);

            if (options.EnableShading)
            {
                foreach (var room in rooms)
                {
                    DrawShading(GetOutline(room.Outline, room.Doors.Select(x => x.DoorLine).ToList(), room.Position), shadePen);
                }
            }

            if (options.EnableHatching)
            {
                var hatchingUsedPoints = new List <Tuple <RectangleGrid2D, List <Vector2> > >();
                foreach (var room in rooms)
                {
                    DrawHatching(room.Outline + room.Position, hatchingUsedPoints, options.HatchingClusterOffset, options.HatchingLength);
                }
            }

            foreach (var room in rooms)
            {
                DrawRoomBackground(room.Outline + room.Position, options.RoomBackgroundColor);

                if (options.EnableGridLines)
                {
                    DrawGrid(room.Outline + room.Position);
                }

                DrawOutline(room.Outline + room.Position, GetOutline(room.Outline, room.Doors.Select(x => x.DoorLine).ToList(), room.Position), outlinePen);
            }

            foreach (var room in rooms)
            {
                if (options.ShowRoomNames && !room.IsCorridor)
                {
                    DrawTextOntoPolygon(room.Outline + room.Position, room.Room.ToString(), options.FontSize);
                }
            }

            outlinePen.Dispose();
            shadePen.Dispose();

            return(bitmap);
        }
 public GeneratedLevel(Dictionary <RoomBase, RoomInstance> roomInstances, LayoutGrid2D <RoomBase> mapLayout, GameObject rootGameObject)
 {
     this.roomInstances = roomInstances;
     this.mapLayout     = mapLayout;
     RootGameObject     = rootGameObject;
 }
예제 #17
0
    private bool GenerateItems(int xoffset, int yoffset, LevelInfo[,] levelStructure, LayoutGrid2D <int> layout)
    {
        var occupiedPoints = new List <AStar.Point>();
        var firstRoom      = layout.Rooms[0];
        var lastRoom       = layout.Rooms[layout.Rooms.Count - 1];

        var indent     = firstRoom.Transformation == Edgar.Geometry.TransformationGrid2D.Identity ? 1 : -1;
        var startPoint = levelStructure[xoffset + firstRoom.Position.X + 1, yoffset + firstRoom.Position.Y + indent];

        startPoint.TileType = TileType.Player;

        indent = lastRoom.Transformation == Edgar.Geometry.TransformationGrid2D.Identity ? 1 : -1;
        var endPoint = levelStructure[xoffset + lastRoom.Position.X + 1, yoffset + lastRoom.Position.Y + indent];

        endPoint.TileType = TileType.Exit;

        var numberOfAttempts = 5;
        var i = 0;
        var obstaclesCoefficient = 15;
        var squareForInnerRoom   = 30;

        while (i < numberOfAttempts)
        {
            foreach (var point in occupiedPoints)
            {
                var tile = levelStructure[point.X, point.Y];
                tile.TileType = TileType.Empty;
            }

            occupiedPoints.Clear();
            obstaclesCoefficient += i * 5;
            squareForInnerRoom   += i * 10;

            GenerateObstacles(xoffset, yoffset, levelStructure, layout, indent, occupiedPoints, obstaclesCoefficient);
            GenerateInnerWalls(xoffset, yoffset, levelStructure, layout, occupiedPoints, squareForInnerRoom);
            GenerateEnemies(xoffset, yoffset, levelStructure, layout, indent, occupiedPoints);
            GenerateCollectible(xoffset, yoffset, levelStructure, layout, occupiedPoints);

            //Debug.Log(AStar.PathFinder.IsPlayerAndEnimiesConnected());

            if (AStar.PathFinder.IsLevelPassable() && PathFinder.IsPlayerAndEnimiesConnected())
            {
                occupiedPoints.Clear();
                return(true);
            }

            Debug.Log("not passable");
            i++;
        }
        occupiedPoints.Clear();
        return(false);
    }
예제 #18
0
        private void mainPictureBox_Paint(object sender, PaintEventArgs e)
        {
            if (layoutToDraw == null)
            {
                return;
            }

            if (exportShownLayoutsCheckbox.Checked)
            {
                DumpSvg();
            }

            UpdateLayoutType();

            var showNames        = showRoomNamesCheckbox.Checked;
            var useOldPaperStyle = useOldPaperStyleCheckbox.Checked;
            var fixedFontSize    = fixedFontSizeCheckbox.Checked ? (int?)fixedFontSizeValue.Value : null;

            if (firstChainToDraw == null)
            {
                firstChainToDraw = layoutToDraw;
                RecomputeFixedScaleAndOffset();
            }
            else
            {
                var previousRoomsCount = firstChainToDraw.Rooms.Count();
                var currentRoomsCount  = layoutToDraw.Rooms.Count();

                if (previousRoomsCount == currentRoomsCount)
                {
                    firstChainToDraw = layoutToDraw;
                    RecomputeFixedScaleAndOffset();
                }
            }

            if (useOldPaperStyle)
            {
                //var bitmap = oldMapDrawer.DrawLayout(layoutToDraw, mainPictureBox.Width, mainPictureBox.Height, showNames, fixedFontSize);
                //e.Graphics.DrawImage(bitmap, new Point(0, 0));
                throw new NotSupportedException();
            }
            else
            {
                //Bitmap bitmap;

                //if (fixedPositionsAndScaleCheckbox.Checked)
                //{
                //	bitmap = wfLayoutDrawer.DrawLayout(layoutToDraw, mainPictureBox.Width, mainPictureBox.Height, showNames, fixedFontSize, fixedScale, fixedOffset);
                //}
                //else
                //{
                //	bitmap = wfLayoutDrawer.DrawLayout(layoutToDraw, mainPictureBox.Width, mainPictureBox.Height, showNames, fixedFontSize);
                //}

                var layoutDrawer = new DungeonDrawer <int>();
                var bitmap       = layoutDrawer.DrawLayout(layoutToDraw, new DungeonDrawerOptions()
                {
                    Width             = mainPictureBox.Width,
                    Height            = mainPictureBox.Height,
                    ShowRoomNames     = showNames,
                    PaddingPercentage = 0.05f,
                    EnableHatching    = true,
                });

                // e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                e.Graphics.DrawImage(bitmap, new Point(0, 0));
            }
        }
 public DungeonGeneratorLevelGrid2D(Dictionary <RoomBase, RoomInstanceGrid2D> roomInstances, LayoutGrid2D <RoomBase> mapLayout, GameObject rootGameObject, LevelDescriptionGrid2D levelDescription) : base(roomInstances, mapLayout, rootGameObject, levelDescription)
 {
 }
예제 #20
0
 public GeneratedLevel(Dictionary <RoomBase, RoomInstanceGrid2D> roomInstances, LayoutGrid2D <RoomBase> mapLayout, GameObject rootGameObject, LevelDescriptionGrid2D levelDescription) : base(roomInstances, rootGameObject, levelDescription)
 {
     this.mapLayout = mapLayout;
 }