无法检测两个矩形是否在碰撞C#

时间:2019-06-18 16:53:35

标签: c#

我正在用C#开发一个程序性的房间生成器,我希望房间不要重叠,并且我很难使它工作。 @Idle_Mind发表评论后,我遇到了一个新问题。该程序产生的图像有许多重叠的房间。贝娄(Bellow)是应该处理相交检查以及将房间放置到tilemap上的类

        public int XSize, YSize;
        private Cell[ , ] cells;
        private List<Room> rooms;

        public Tilemap(int xSize, int ySize)
        {
            XSize = xSize;
            YSize = ySize;
            rooms = new List<Room>();
            cells = new Cell[XSize, YSize];

            for (int y = 0; y < YSize; y++)
            {
                for (int x = 0; x < XSize; x++)
                {
                    cells[x, y].type = CellType.Empty;
                }
            }

            for (int i = 0; i < 10; i++)
            {
                GenerateRandomRoomSafe(10);
            }
        }

        private Room GetRoomBounds()
        {

            Utils.Int2 min = new Utils.Int2(0, 0);
            Utils.Int2 max = new Utils.Int2(XSize,YSize);
            Utils.Int2 q1 = Utils.GetRandomCoords(min, max);

            max.X = XSize - 1 - q1.X;
            max.Y = YSize - 1 - q1.Y;

            Utils.Int2 siz = Utils.GetRandomCoords(min, max);
            Room check = new Room(q1.X, q1.Y, siz.X, siz.Y);


            return check;
        }

        public void GenerateRandomRoomSafe(int maxTries)
        {
            Room check = new Room(0, 0, 0, 0);
            bool isValid = false;
            int tries = 0;

            if (rooms.Count == 0)
            {
                isValid = true;
                check = GetRoomBounds();
                tries = 1;
            }
            else
            {
                while (!isValid && tries < maxTries)
                {
                    check = GetRoomBounds();
                    for (int i = 0; i < rooms.Count; i++)
                    {
                        if (!rooms[i].Walls.IntersectsWith(check.Walls))
                        {
                            isValid = true;
                            break;
                        }
                    }
                    tries++;
                }
            }

            if (isValid)
            {
                Console.WriteLine(check + " was placed after " + tries + " tries");
                PlaceRoomUnsafe(check);
            }
        }

        public void PlaceRoomUnsafe(Room r)
        {
            for (int y = r.Walls.Y; y <= r.Walls.Y + r.Walls.Height; y++)
            {
                cells[r.Walls.X, y].type = CellType.Wall;
            }
            for (int y = r.Walls.Y; y <= r.Walls.Y + r.Walls.Height; y++)
            {
                cells[r.Walls.X + r.Walls.Width, y].type = CellType.Wall;
            }
            for (int x = r.Walls.X; x <= r.Walls.X + r.Walls.Width; x++)
            {
                cells[x, r.Walls.Y].type = CellType.Wall;
            }
            for (int x = r.Walls.X; x <= r.Walls.X + r.Walls.Width; x++)
            {
                cells[x, r.Walls.Y + r.Walls.Height].type = CellType.Wall;
            }

            for (int y = r.Floor.Y; y < r.Floor.Y + r.Floor.Height; y++)
            {
                for (int x = r.Floor.X; x < r.Floor.X + r.Floor.Width; x++)
                {
                    cells[x, y].type = CellType.Floor;
                }
            }
            rooms.Add(r);
        }

        public void GenerateRandomRoomUnsafe()
        {
            Room r = GetRoomBounds();
            PlaceRoomUnsafe(r);
        }


        public int GetCellPixel(int x, int y)
        {
            return (int) cells[x, y].type;
        }


        public class Room
        {
            public Rectangle Walls;
            public Rectangle Floor;

            public Room(int q1X, int q1Y, int xSize, int ySize)
            {
                Walls.X = q1X;
                Walls.Y = q1Y;
                Walls.Width = xSize;
                Walls.Height = ySize;
                Floor.X = q1X + 1;
                Floor.Y = q1Y + 1;
                Floor.Width = xSize - 1;
                Floor.Height = ySize - 1;
            }

            public override string ToString()
            {
                return "[Walls: " + Walls + "\n Floor: " + Floor + "]";
            }
        }
    }

下面的图片仅供参考Image

1 个答案:

答案 0 :(得分:1)

您在GenerateRandomRoomSafe()中的逻辑是倒数。

在此代码块中:

while (!isValid && tries < maxTries)
{
    check = GetRoomBounds();
    for (int i = 0; i < rooms.Count; i++)
    {
        if (!rooms[i].Walls.IntersectsWith(check.Walls))
        {
            isValid = true;
            break;
        }
    }
    tries++;
}

您的意思是,“如果它不与至少一个房间相交,那么它必须是有效的。”

仅仅是因为它不与当前房间相交,并不意味着它就不会与其他房间相交!

它看起来应该更像:(注意评论)

while (!isValid && tries < maxTries)
{
    isValid = true; // assume it's good until proven otherwise
    check = GetRoomBounds();
    for (int i = 0; i < rooms.Count; i++)
    {
        if (rooms[i].Walls.IntersectsWith(check.Walls)) // if it DOES intersect...
        {
            isValid = false; // .. then set valid to false.
            break;
        }
    }
    tries++;
}

因此,我们首先假设它是有效的,然后当我们遇到一个与DOES相交的房间时,将valid设置为false并停止for循环,以便可以尝试另一个随机房间(假设我们没有超过尝试次数)。

它产生的一些地图:

enter image description here

相关问题