1

当我的球击中我的 Breakout 克隆中的砖块时,我在对球应用正确的速度变化时遇到了一些麻烦。在上一个问题中,我被建议使用连续碰撞检测,以及其他方法,例如在球撞到角落时找到球和砖块之间的交点,以确定球应该反射的方向。我已将此应用于下面的代码,但在某些情况下球会完全穿过一堆砖块。当它碰到移动的砖块时,这一点更加明显。

在 Level.cs 更新方法中:

Bricks.ForEach(brick => Balls.ForEach(ball => ball.Collide(brick)));

在 Ball.cs 中:

public bool Touching(Brick brick)
{
    var position = Position + (Velocity * Speed);
    return position.Y + Size.Y >= brick.Position.Y &&
              position.Y <= brick.Position.Y + brick.Size.Y &&
              position.X + Size.X >= brick.Position.X &&
              position.X <= brick.Position.X + brick.Size.X && brick.Health > 0 && brick.Lifespan == 1F;
}

public void Collide(Brick brick)
{
    if (!Touching(brick)) return;

    var position = Position + (Velocity * Speed);

    var bounds = new Rectangle((int)position.X, (int)position.Y, Texture.Width, Texture.Height);

    var nonCCDBounds = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);

    if (bounds.Intersects(brick.Top) || bounds.Intersects(brick.Bottom))
    {
        var change = new Vector2(Velocity.X, -Velocity.Y);
        if (bounds.Intersects(brick.Left) || bounds.Intersects(brick.Right))
        {
            var intersection = Rectangle.Intersect(bounds, brick.Texture.Bounds);
            var nonCCDIntersection = Rectangle.Intersect(nonCCDBounds, brick.Texture.Bounds);
            if (intersection.Width < intersection.Height || nonCCDIntersection.Width < nonCCDIntersection.Height){
                change = new Vector2(-Velocity.X, Velocity.Y);
            }
        }
        if (bounds.Intersects(brick.Top))
        {
            if (level.GetBrick(new Vector2(brick.GridPosition.X, brick.GridPosition.Y - 1)) != null)
                change = new Vector2(-Velocity.X, Velocity.Y);
            else if ((Position - Velocity).Y > brick.Position.Y)
                change = new Vector2(-Velocity.X, Velocity.Y);
        }
        if (bounds.Intersects(brick.Bottom))
        {
            if (level.GetBrick(new Vector2(brick.GridPosition.X, brick.GridPosition.Y + 1)) != null)
                change = new Vector2(-Velocity.X, Velocity.Y);
            else if ((Position - Velocity).Y < brick.Position.Y + brick.Texture.Bounds.Height)
                change = new Vector2(-Velocity.X, Velocity.Y);
        }
        ReflectBall(brick, change);
        return;
    }

    if (bounds.Intersects(brick.Left) || bounds.Intersects(brick.Right))
    {
        var change = new Vector2(-Velocity.X, Velocity.Y);
        if (bounds.Intersects(brick.Top) || bounds.Intersects(brick.Bottom))
        {
            var intersection = Rectangle.Intersect(bounds, brick.Texture.Bounds);
            var nonCCDIntersection = Rectangle.Intersect(nonCCDBounds, brick.Texture.Bounds);
            if (intersection.Width > intersection.Height || nonCCDIntersection.Width > nonCCDIntersection.Height)
            {
                change = new Vector2(Velocity.X, -Velocity.Y);
            }
        }
        if (bounds.Intersects(brick.Left))
        {
            if (level.GetBrick(new Vector2(brick.GridPosition.X - 1, brick.GridPosition.Y)) != null)
                change = new Vector2(Velocity.X, -Velocity.Y);
            else if ((Position - Velocity).X > brick.Position.X)
                change = new Vector2(Velocity.X, -Velocity.Y);
        }
        if (bounds.Intersects(brick.Right))
        {
            if (level.GetBrick(new Vector2(brick.GridPosition.X + 1, brick.GridPosition.Y)) != null)
                change = new Vector2(Velocity.X, -Velocity.Y);
            else if ((Position - Velocity).X < brick.Position.X + brick.Texture.Bounds.Width)
                change = new Vector2(Velocity.X, -Velocity.Y);
        }
        ReflectBall(brick, change);
    }
}

public void ReflectBall(Brick brick, Vector2 reflection)
{
    Position = Position - Velocity;

    Velocity = reflection;

    if (brick.Health < 9)
    {
        brick.Health--;
        brick.Life --;
    }

    if (brick.Health > 0 && brick.Life > 0)
    {
        brick.Texture = Assets.GetBrick(brick.TextureName, brick.Health);
    }
}

这有点乱,但这是我最接近体面的碰撞。如果有一种快速的方法可以找出碰撞点并应用正确的速度变化,那将会容易得多。

4

0 回答 0