2

我有一个简单的 BreakOut 游戏(垂直,沿底部划桨)启动并运行,但碰撞检测有点偏离。我使用 Rectangle.Intersect 来初步检查球是否完全与给定的砖相交,然后如果它确实还有 4 个 Intersect 调用来检查球是垂直碰撞(砖的一侧,左+​​右)还是水平(砖的顶部+底部)。在某些情况下,当球在 2 个水平相邻的砖块的交叉点附近以锐角与砖块相撞时,它会将它们都移除并继续向上。我认为这是双重碰撞。我已经强行退出了 foreach 循环,它在找到矩形相交的那一刻检查矩形相交,但这并没有解决问题。

这是在游戏类的主要 Update() 函数中:

        foreach (Brick brick in bricks)
        {
            if (brick.CheckCollision(ball))
            {
                break;
            }
        }

这是 Brick.CheckCollision() 函数:

    public bool CheckCollision(Ball ball)
    {
        if (alive && ball.Bounds.Intersects(location))
        {
            alive=false;
            ball.Deflection(this);
            return true;
        }
        return false;
    }

这就是 Ball.Deflection() 函数。在此,我使用没有宽度/高度的矩形来标记砖的侧面。不确定这是否是正确的方法:

    public void Deflection(Brick brick)
    {
        //For vertical collision (top or bottom of brick) invert Y motion
        if (this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Top, brick.Location.Right - brick.Location.Left, 0)) ||
            this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Bottom, brick.Location.Right - brick.Location.Left, 0)))
        {
            motion.Y *= -1;
            return;
        }
        //For horizontal collision (left or right side of brick) invert X motion
        if (this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Top, 0, brick.Location.Bottom - brick.Location.Top)) ||
            this.Bounds.Intersects(new Rectangle(brick.Location.Right, brick.Location.Top, 0, brick.Location.Bottom - brick.Location.Top)))
        {
            motion.X *= -1;
            return;
        }
    }

我假设我犯了一个明显的逻辑错误,但如果可以改进一般方法,我会全神贯注!

4

1 回答 1

0

通过与 itsme86 在评论中的讨论,我解决了我的问题。我添加了日志记录(由 bmm6o 推荐),并确认这是由于球在一帧内移动太远而在下一帧仍部分位于相邻块内造成的碰撞加倍。我决定保持逻辑简单,当我反转它的方向时,将球移回它相交的块的边缘。这是在中间没有 Draw() 函数的情况下完成的,以免产生口吃效果。我正在努力观察任何跳跃或口吃,所以如果有的话,它是不可见的。

于 2012-09-10T09:07:35.607 回答