-3

我正在尝试根据这个算法为我一直在从事的项目创建一个地牢生成器。我已经把所有东西都搞定了,但是我的数组(图 1)似乎并没有因为某种原因提供地图数据。我正在使用三种类型的数据来确定地图中的单元格是否为空 (0)、角色可以位于的空间 (1)、走廊 (2) 或墙壁 (3)。

我在这部分有点卡住了,所以感谢您的帮助!

编辑:问题是地图对象没有将数据存储在图 1 所示的循环中。抱歉如此含糊。

(图。1)

        for (int i = 0; i < roomList.Count; i++)
        {
            for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
            {
                for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
                {
                    map[x, y] = 1;
                }
            }
        }

(我所有的相关代码)

namespace Project
{
    }
    public class Room
    {
        int xValue, yValue, widthValue, heightValue;

        public int X
        {
            get { return xValue; }
            set { xValue = value; }
        }
        public int Y
        {
            get { return yValue; }
            set { yValue = value; }
        }
        public int W
        {
            get { return widthValue; }
            set { widthValue = value; }
        }
        public int H
        {
            get { return heightValue; }
            set { heightValue = value; }
        }
    }
public class DungeonGenerate
{
    public int baseWidth = 513;
    public int baseHeight = 513;
    public int width = 64;
    public int height = 64;
    Color[,] arrayColor;
    Random rand = new Random();
    Room room = new Room();
    Rectangle[,] rectMap;

    public void Generate()
    {
        rectMap = new Rectangle[baseWidth, baseHeight];
        //Creates a 2-D Array/Grid for the Dungeon
        int[,] map = new int[baseWidth, baseHeight];
        //Determines all the cells to be empty until otherwise stated
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                map[x, y] = 0;
            }
        }

        //Determines the amount of rooms in the dungeon
        int minRooms = (width * height) / 300;
        int maxRooms = (width * height) / 150;
        int amountOfRooms = rand.Next(minRooms, maxRooms);

        //Room dimensions
        int widthRoot = Convert.ToInt32(Math.Round(Math.Sqrt(width * 2)));
        int heightRoot = Convert.ToInt32(Math.Round(Math.Sqrt(height * 2)));
        int minWidth = Convert.ToInt32(Math.Round((width * .5) / widthRoot));
        int maxWidth = Convert.ToInt32((width * 2) / widthRoot);
        int minHeight = Convert.ToInt32(Math.Round(height * .5) / heightRoot);
        int maxHeight = Convert.ToInt32((height * 2) / heightRoot);

        //Creates the rooms
        List<Room> roomList = new List<Room>(amountOfRooms);

        for (int i = 0; i < amountOfRooms; i++)
        {
            bool ok = false;
            do
            {
                room.X = rand.Next(width);
                room.Y = rand.Next(height);
                room.W = (rand.Next(maxWidth)) + minWidth;
                room.H = (rand.Next(maxHeight)) + minHeight;

                if (room.X + room.W >= width && room.Y + room.H >= height)
                {
                    continue;
                }
                for (int q = 0; q < roomList.Count; q++)
                {
                    if (room.X > roomList[q].X && room.X < roomList[q].X + room.W && room.Y > roomList[q].Y && room.Y < roomList[q].Y + room.H)
                    {
                        ok = false;
                        break;
                    }
                }
                ok = true;
                roomList.Add(room);
            } while (!ok);
        }
        //This will create hallways that lead to and from the rooms
        int connectionCount = roomList.Count;
        List<Point> connectedCells = new List<Point>((width * height));
        for (int i = 0; i < connectionCount; i++)
        {
            Room roomA = roomList[i];
            int roomNum = i;

            while (roomNum == i)
            {
                roomNum = rand.Next(roomList.Count);
            }

            Room roomB = roomList[roomNum];

            //Increasing this will make the hallway more straight, decreasing it will make the hallway more skewed
            int sidestepChance = 10;

            Point pointA = new Point(x: (rand.Next(roomA.W)) + roomA.X, y: (rand.Next(roomA.H)) + roomA.Y);
            Point pointB = new Point(x: (rand.Next(roomB.W)) + roomB.X, y: (rand.Next(roomB.H)) + roomB.Y);

            while (pointA != pointB)
            {
                int num = rand.Next() * 100;

                if (num < sidestepChance)
                {
                    if (pointB.X != pointA.X)
                    {
                        if (pointB.X > pointA.X)
                        {
                            pointB.X--;
                        }
                        else
                        {
                            pointB.X++;
                        }
                    }
                }
                else if(pointB.Y != pointA.Y)
                {
                    if (pointB.Y > pointA.Y)
                    {
                        pointB.Y--;
                    }
                    else
                    {
                        pointB.Y++;
                    }
                }
            }

            if (pointB.X < width && pointB.Y < height)
            {
                connectedCells.Add(pointB);
            }
        }

        //Fills the room with data
        for (int i = 0; i < roomList.Count; i++)
        {
            for (int x = roomList[i].X; x < (roomList[i].X + roomList[i].W); x++)
            {
                for (int y = roomList[i].Y; y < (roomList[i].Y + roomList[i].H); y++)
                {
                    map[x, y] = 1;
                }
            }
        }

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                if (map[x, y] == 0)
                {
                    bool wall = false;
                    for (int yy = y - 2; yy < y + 2; yy++)
                    {
                        for (int xx = x - 2; xx < x + 2; xx++)
                        {
                            if (xx > 0 && yy > 0 && xx < width && yy < height)
                            {
                                if (map[xx, yy] == 1 || map[xx, yy] == 2)
                                {
                                    map[x, y] = 3;
                                    wall = true;
                                }
                            }
                        }
                        if (wall)
                        {
                            break;
                        }
                    }
                }
            }
        }

        //Rendering the Map and giving it some Color (Sort of)!
        int scaler = baseWidth / width;

        for (int x = 0; x < baseWidth; x++)
        {
            for (int y = 0; y < baseHeight; y++)
            {
                rectMap[x, y] = new Rectangle(x, y, 1, 1);
                arrayColor = new Color[baseWidth, baseHeight];
                switch (map[x, y])
                {
                    case 0:
                        arrayColor[x, y] = new Color(0,0,0);
                        break;
                    case 1:
                        arrayColor[x, y] = new Color(0,0,0);
                        break;
                    case 2:
                        arrayColor[x, y] = new Color(0,0,0);
                        break;
                    case 3:
                        arrayColor[x, y] = new Color (0,0,0);
                        break; 
                }
            }
        }
    }
    public Rectangle[,] GetMap()
    {
        return rectMap;
    }
    public Color[,] GetColors()
    {
        return arrayColor;
    }
}
4

1 回答 1

2

for您要填充的 -loop 中,您不会每次都roomList实例化一个新的。Room您只是在操作同一个Room对象并将其重新添加到列表中,因此roomList只会包含对同一Room对象的许多引用。尝试room从您的类中删除该字段DungeonGenerate并改用局部变量:

for (int i = 0; i < amountOfRooms; i++)
{
    bool ok = false;
    do
    {
        var room = new Room();
        ...
        roomList.Add(room);
    } while (!ok);
}
于 2013-10-05T21:22:36.657 回答