I made a simple dungeon generator in C# using MonoGame that works by placing rooms in a grid and connecting them via "tunnels". I would like feedback on how this could be improved in terms of efficiency and code style. Also, please ignore the Render()
function in DungeonGenerator.cs
as it is only temporary.
Here is one example of a generated dungeon:
SimpleRoomGenerator.cs
using System;
namespace Roguelike
{
public class SimpleRoomGenerator : DungeonGenerator
{
private struct Room
{
public const int MinWidth = 5;
public const int MinHeight = 5;
public const int MaxHeight = 9;
public const int MaxWidth = 9;
public int XPos { get; set; }
public int YPos { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int CentreX { get { return XPos + (Width / 2); } }
public int CentreY { get { return YPos + (Height / 2); } }
}
public const int NumRooms = 10;
public SimpleRoomGenerator(int width, int height) : base(width, height)
{
}
public override void Generate()
{
dungeon = new int[width, height];
Room previousRoom = new Room();
for (int i = 0; i < NumRooms; i++)
{
Room room = new Room();
room.XPos = random.Next(0, width - Room.MaxWidth);
room.YPos = random.Next(0, height - Room.MaxHeight);
room.Width = random.Next(Room.MinWidth, Room.MaxWidth);
room.Height = random.Next(Room.MinHeight, Room.MaxHeight);
for (int y = room.YPos; y < room.YPos + room.Height; y++)
{
for (int x = room.XPos; x < room.XPos + room.Width; x++)
{
dungeon[x, y] = 1;
}
}
if (i > 0)
{
int startX = Math.Min(room.CentreX, previousRoom.CentreX);
int startY = Math.Min(room.CentreY, previousRoom.CentreY);
int endX = Math.Max(room.CentreX, previousRoom.CentreX);
int endY = Math.Max(room.CentreY, previousRoom.CentreY);
if (random.Next(1) == 0)
{
for (int x = startX; x < endX; x++)
dungeon[x, previousRoom.CentreY] = 1;
for (int y = startY; y < endY + 1; y++)
dungeon[room.CentreX, y] = 1;
}
else
{
for (int y = startY; y < endY + 1; y++)
dungeon[previousRoom.CentreX, y] = 1;
for (int x = startX; x < endX; x++)
dungeon[x, room.CentreY] = 1;
}
}
previousRoom = room;
}
}
public override void Update()
{
}
}
}
DungeonGenerator.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Roguelike
{
public abstract class DungeonGenerator
{
public const int TileWidth = 8;
public const int TileHeight = 8;
protected Random random;
protected int[,] dungeon;
protected int width;
protected int height;
public DungeonGenerator(int width, int height)
{
this.width = width;
this.height = height;
random = new Random();
dungeon = new int[width, height];
}
public abstract void Generate();
public abstract void Update();
public void Render(SpriteBatch spriteBatch, ContentManager content)
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (dungeon[x, y] != 0)
spriteBatch.Draw(content.Load<Texture2D>(dungeon[x, y].ToString()), new Rectangle(x * TileWidth, y * TileHeight, TileWidth, TileHeight), Color.White);
}
}
}
}
}