【问题标题】:C# Quickly checking if two pictureboxes touch each other?C#快速检查两个图片框是否相互接触?
【发布时间】:2017-09-08 08:34:16
【问题描述】:

我正在用 Visual C# 创建我的第一个非控制台游戏。 我有一个播放器是图片框,障碍物也是图片框。 现在,当我在随机位置创建障碍物(图片框)时,我想检查它是否已经接触到其他障碍物。

这是我现在拥有的:

Picturebox obstacles = new Picturebox[20];
for (int i = 0; i < obstacles.Length; i++)
{
    DateTime date = DateTime.Now;
    Random randomNumber = new Random(date.Second * (date.Minute / 2) ^ 2 + date.Hour * 123 + (i ^ 9 + i / 2));
    obstacles[i] = new PictureBox();
    obstacles[i].Image = Properties.Resources.es;
    obstacles[i].Size = new Size(25, 50);
    obstacles[i].Location = new Point(randomNumber.Next(640 - obstacles[i].Image.Width), randomNumber.Next(topBar.Height, 480 - obstacles[i].Image.Height));
    if (IsTouching(obstacles[i], player))
    {
        i--;
    }
    else
    {
        bool tmp = true;
        for (int j = 0; j < obstacles.Length; j++)
        {
            if (obstacles[j] != null && j != i)
            {
                if (IsTouching(obstacles[j], obstacles[i]))
                {
                    tmp = false;
                    break;
                }
            }
        }
        if (tmp)
        {
            Controls.Add(obstacles[i]);
        }
        else
        {
            i--;
        }
    }
}

这就是我的方式,但我知道它不是很有效,所以任何更好的想法,因为创建这些障碍需要一段时间(约 5 秒)。 这是我的 IsTouching 方法,也有点烂,有人有更好的想法吗?

private bool IsTouching(PictureBox obj1, PictureBox obj2)
{
    Point[] obj1Points = new Point[(obj1.Width * obj1.Height) - ((obj1.Width - 2) * (obj1.Height - 2))];
    int count = 0;
    for (int x = obj1.Left + 1; x < obj1.Left + obj1.Width - 1; x++)
    {
        obj1Points[count] = new Point(x, obj1.Top);
        obj1Points[count + 1] = new Point(x, obj1.Top + obj1.Height);
        count += 2;
    }
    for (int y = obj1.Top; y < obj1.Top + obj1.Height; y++)
    {
        obj1Points[count] = new Point(obj1.Left, y);
        obj1Points[count + 1] = new Point(obj1.Left + obj1.Width, y);
        count += 2;
    }

    Point[] obj2Points = new Point[(obj2.Width * obj2.Height) - ((obj2.Width - 2) * (obj2.Height - 2))];
    count = 0;
    for (int x = obj2.Left + 1; x < obj2.Left + obj2.Width - 1; x++)
    {
        obj2Points[count] = new Point(x, obj2.Top);
        obj2Points[count + 1] = new Point(x, obj2.Top + obj2.Height);
        count += 2;
    }
    for (int y = obj2.Top; y < obj2.Top + obj2.Height; y++)
    {
        obj2Points[count] = new Point(obj2.Left, y);
        obj2Points[count + 1] = new Point(obj2.Left + obj2.Width, y);
        count += 2;
    }

    for (int obj2Point = 0; obj2Point < obj2Points.Length; obj2Point++)
    {
        for (int obj1Point = 0; obj1Point < obj1Points.Length; obj1Point++)
        {
            if (obj2Points[obj2Point].X == obj1Points[obj1Point].X && obj2Points[obj2Point].Y == obj1Points[obj1Point].Y)
            {
                return true;
            }
        }
    }
    return false;
}

它的作用:检查给定的两个参数边缘是否相互接触。所以基本上只是一个碰撞检测,任何人都有任何想法,因为我对这个东西有点陌生?

【问题讨论】:

    标签: touch collision-detection picturebox


    【解决方案1】:

    如果我们假设所有障碍物都是实心的(即,如果另一个障碍物在另一个障碍物内部,则两个障碍物接触),您可以使用以下方法:

    private bool IsTouching(PictureBox p1, PictureBox p2)
    {
        if (p1.Location.X + p1.Width < p2.Location.X) 
            return false;
        if (p2.Location.X + p2.Width < p1.Location.X)
            return false;
        if (p1.Location.Y + p1.Height < p2.Location.Y)
            return false;
        if (p2.Location.Y + p2.Height < p1.Location.Y)
            return false;
        return true;
    }
    

    我测试了您当前的 IsTouching 方法,发现它在某些极端情况下会失败,例如在 this one 中(它声称它们没有接触,尽管它们是接触的)。我的方法也适用于这些极端情况。

    【讨论】:

      【解决方案2】:

      有一个简单的代码行,但有时它也可能在某些角落部分失败。

      if(player1.Bounds.IntersectWith(player2.Bounds){
        //Do something
      }
      

      将player1替换为图片框的名称,与player2 ofc相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-25
        • 2015-01-06
        • 2011-03-14
        • 2013-09-23
        • 2017-11-30
        • 1970-01-01
        相关资源
        最近更新 更多