简体   繁体   English

2D碰撞检测表现有趣

[英]2D Collision Detection acting funny

I've got a simple BreakOut game (vertical, paddle along bottom) up and running but the collision detection is a bit off. 我已经安装并运行了一个简单的BreakOut游戏(垂直,沿底部划桨),但是碰撞检测有些偏离。 I'm using a Rectangle.Intersect to initially check if the ball intersects the given brick at all and then if it does have 4 more Intersect calls to check whether the ball is colliding vertically (side of brick, left+right) or horizontally (top+bottom of brick). 我正在使用Rectangle.Intersect来首先检查球是否与给定的砖相交,然后是否确实还有4个相交调用来检查球是垂直碰撞(砖的侧面,左+右)还是水平碰撞(砖的顶部+底部)。 On some occasions when the ball collides with a brick at an acute angle near the intersection of 2 horizontally adjacent bricks it removes both of them and continues in an upward direction. 在某些情况下,当球与一块砖块以锐角在2个水平相邻砖块的相交处碰撞时,它们会同时去除它们并沿向上方向继续。 I assume this is a double up of collisions. 我认为这是碰撞的两倍。 I've forcibly exited the foreach loop which checks for rectangle intersects the moment it finds one but this hasn't resolved issue. 我已经强行退出了foreach循环,该循环会在找到矩形后立即检查矩形是否相交,但这尚未解决。

This is in the main Update() function of the game class: 这在游戏类的主要Update()函数中:

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

This is the Brick.CheckCollision() function: 这是Brick.CheckCollision()函数:

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

And this is the Ball.Deflection() function. 这是Ball.Deflection()函数。 In this I'm using rectangles with no width/heigth to mark the sides of the brick. 在此,我使用没有宽度/高度的矩形来标记砖的侧面。 Not sure if that is the correct way: 不知道这是否是正确的方法:

    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;
        }
    }

I assume I'm making a blatantly obvious logic error but if the general approach can be improved I'm all ears! 我以为我犯了一个非常明显的逻辑错误,但是如果可以改善常规方法,我会不知所措!

Through discussion in the comments with itsme86 I've resolved my issues. 通过与itsme86的评论中的讨论,我已经解决了我的问题。 I added logging (recommended by bmm6o) and confirmed that it was a doubling up of collisions caused by the ball travelling too far inside a block on one frame and still being partially inside adjacent block on next frame. 我添加了日志记录(由bmm6o推荐),并确认这是由于球在一个帧上的一个块内移动得太远而在下一帧上仍部分位于相邻块内而导致的碰撞增加了一倍。 I've decided to keep the logic simple and just move the ball back to the edge of the block it intersects when I reverse it's direction. 我已经决定保持逻辑简单,只要将球反转到方向相反时,将球移回到与之相交的方块边缘即可。 This is done with no Draw() function in between so as not to produce stuttering effect. 这样做之间没有Draw()函数,以免产生卡顿现象。 I am struggling to observe any jumps or stuttering at all so if there is any it's not visible. 我努力观察根本没有跳跃或停顿,因此,如果看不到任何跳跃或停顿。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM