在WPF画布上检测两个矩形之间的碰撞

4
我对编程非常陌生,我选择了C#作为入门语言。现在我正在尝试制作我的第一个游戏,我决定做贪吃蛇。到目前为止,我一直在研究这个问题,但是所有我看到的答案都是针对使用不同方法移动蛇的人的。
我的程序使用两个double值(left和top)来存储蛇在画布上的位置。我的程序还使用两个double值来表示游戏中的“食物”,称为randomFoodSpawnLeft和randomFoodSpawnTop。
我的问题是:如何仅使用left和top值检测两个矩形对象之间的碰撞?我很困惑。
snakeWindow是窗口,snakeHead是代表蛇的矩形,left是蛇的左侧值,top是蛇的顶部值。
void timer_Tick(object sender, EventArgs e)
    {
        double left = Canvas.GetLeft(snakeHead);
        double top = Canvas.GetTop(snakeHead);

        if (keyUp)
        {
            top -= 3;
        }
        else if (keyDown)
        {
            top += 3;
        }
        else if (keyLeft)
        {
            left -= 3;
        }

        else if (keyRight)
        {
            left += 3;
        }
        // These statements see if you have hit the border of the window, default is 1024x765
        if (left < 0)
        {
            left = 0;
            gameOver = true;
        }
        if (top < 0)
        {
            top = 0;
            gameOver = true;
        }
        if (left > snakeWindow.Width)
        {
            left = 0;
            gameOver = true;
        }
        if (top > snakeWindow.Height)
        {
            top = 0;
            gameOver = true;
        }
        // Statements that detect hit collision between the snakeHead and food
        //
        if (foodEaten == true)
        {
            spawnFood();
            textBlockCurrentScore.Text += 1;
        }

            // If gameOver were to be true, then the game would have to end. In order to accomplish this I display to the user that the game is over
            // and the snakeHead is disabled, and should restart.
            if (gameOver == true)
        {
            keyRight = false;
            keyLeft = false;
            keyUp = false;
            keyDown = false;
            top = 0;
            left = 0;

            textBlockGameOver.Text = "GAME OVER!";
            snakeCanvas.Background = Brushes.Blue;
        }


        Canvas.SetLeft(snakeHead, left);
        Canvas.SetTop(snakeHead, top);
    }

可以使用一个 if 语句替代四个来执行碰撞测试(参见 intersect)。问题不清楚:每个矩形都有坐标(左,上)和尺寸(宽度,高度)。问题在哪里? - Sinatr
那么我该如何处理Left、Top、Width和Height呢?如何将蛇与食物进行比较?这些就足以执行intersectsWith了吗? - Cinnamonbun
很不幸的是,当我尝试使用IntersectsWith时,它显示Rectangle没有包含intersectsWith的定义。 - Cinnamonbun
IntersectsWithSystem.Drawing.Rectangle 上的一个方法;也许你正在使用 System.Windows.Shapes.Rectangle - Scroog1
是的,我相信我正在使用Shapes.Rectangle,那么你如何检测与Shapes的碰撞呢? - Cinnamonbun
显示剩余3条评论
1个回答

6
你可以使用 System.Windows.Rect.IntersectsWith 来实现。试试这样做:
Rect rect1 = new Rect(left1, top1, widht1, height1);
Rect rect2 = new Rect(left2, top2, widht2, height2);

bool intersects = rect1.IntersectsWith(rect2);

当然,您需要检查蛇头与所有其他部位是否匹配。

1
如果您将身体部位存储为 Rect 列表,则可以使用漂亮的 LINQ 语句:eatenSelf = bodyParts.Any(part => snakeHead.IntersectsWith(part)); - Scroog1
当我尝试声明 "System.Windows.Rect.IntersectsWith" 时,出现了错误。它告诉我 Rect 是一种类型,在给定的上下文中无效。 - Cinnamonbun
@Cinnamonbun 类型是 System.Windows.RectIntersectsWith 是该类型的实例方法。 - René Vogt
@RenéVogt 对不起,我真的很新于编程,我想我甚至还没有理解我在做什么。我应该在我的命名空间Game下声明System.Windows.Rect.intersectsWith吗? - Cinnamonbun
@Cinnamonbun,你不需要声明它。你可能想在你的文件中添加 using System.Windows;。然后你就可以像使用其他类型一样在 C# 中使用 Rect - René Vogt
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接