从Rectangle.Intersects()获取碰撞详细信息


9

我有一个Breakout游戏,在该游戏中,有时会通过以下方式检测到球和桨之间的碰撞:

// Ball class
rectangle.Intersects(paddle.Rectangle);

有什么办法可以获取当前碰撞的确切坐标或有关碰撞的任何详细信息XNA API

我考虑做一些基本的计算,例如比较碰撞时每个物体的精确坐标。它看起来像这样:

// Ball class
if((rectangle.X - paddle.Rectangle.X) < (paddle.Rectangle.Width / 2))
    // Collision happened on the left side
else
    // Collision happened on the right side

但是我不确定这是正确的方法。

你们对我可能要使用的引擎有任何提示吗?甚至使用这种方法的良好编码习惯?

Answers:


8

XNA的矩形非常有限。该Rectangle.Intersects()方法仅返回布尔结果,因此如果需要详细信息,则需要自己进行更多测试。但是,您可以使用Rectangle.Intersect(Rectangle, Rectangle)方法获得两个重叠的矩形。至少,这将为您提供一些有关深度和位置的信息。


get the rectangle where the two overlap可以使用此功能吗?XNA API还是我必须下载一些其他内容,例如Platformer Starter Kit
丹尼尔·里贝罗

1
这是哪一种方法?我不记得XNA 4.0支持Rectangle Rectangle.Intersects(...)
ashes999

有人在stackoverflow上给了我权利:msdn.microsoft.com/en-us/library/…–
Daniel Ribeiro

好的,使用返回的Rectangle,如何检查被球撞到的桨的位置?
丹尼尔·里贝罗

如果您知道桨和球相交,那么您将使用首先检查的桨矩形的位置信息,即rectangle.Xrectangle.Y或想要访问的任何东西。
2012年

4

更新:如果您使用的是MonoGame,则从3.0 Beta开始Rectangle Rectangle.Intersect(rectangle, rectangle)不存在。您可以改用XNA Platformer套件中的以下代码。


您可以下载XNA Platformer入门套件(已移植到Windows 7)。它附带了一个辅助扩展方法,该方法返回一个描述两个矩形相交的矩形:

static class RectangleExtensions
    {
        /// <summary>
        /// Calculates the signed depth of intersection between two rectangles.
        /// </summary>
        /// <returns>
        /// The amount of overlap between two intersecting rectangles. These
        /// depth values can be negative depending on which wides the rectangles
        /// intersect. This allows callers to determine the correct direction
        /// to push objects in order to resolve collisions.
        /// If the rectangles are not intersecting, Vector2.Zero is returned.
        /// </returns>
        public static Vector2 GetIntersectionDepth(this Rectangle rectA, Rectangle rectB)
        {
            // Calculate half sizes.
            float halfWidthA = rectA.Width / 2.0f;
            float halfHeightA = rectA.Height / 2.0f;
            float halfWidthB = rectB.Width / 2.0f;
            float halfHeightB = rectB.Height / 2.0f;

            // Calculate centers.
            Vector2 centerA = new Vector2(rectA.Left + halfWidthA, rectA.Top + halfHeightA);
            Vector2 centerB = new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

            // Calculate current and minimum-non-intersecting distances between centers.
            float distanceX = centerA.X - centerB.X;
            float distanceY = centerA.Y - centerB.Y;
            float minDistanceX = halfWidthA + halfWidthB;
            float minDistanceY = halfHeightA + halfHeightB;

            // If we are not intersecting at all, return (0, 0).
            if (Math.Abs(distanceX) >= minDistanceX || Math.Abs(distanceY) >= minDistanceY)
                return Vector2.Zero;

            // Calculate and return intersection depths.
            float depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
            float depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;
            return new Vector2(depthX, depthY);
        }

        /// <summary>
        /// Gets the position of the center of the bottom edge of the rectangle.
        /// </summary>
        public static Vector2 GetBottomCenter(this Rectangle rect)
        {
            return new Vector2(rect.X + rect.Width / 2.0f, rect.Bottom);
        }
}

非常感谢您提供此链接。请问您为什么需要使用修改后的版本?那是港口官员吗?
Daniel Ribeiro

@DanielRibeiro我检查了我的历史记录,显然我根本没有修改它。该港口是非官方的;我根本找不到原件。它适用于MonoGame / C#,对我来说足够好。
ashes999

但是有一个原始端口,对吗?这不是应该这么简单的功能吗?无论如何,我不是使用MonoGame,而只是使用XNA。您还会建议我使用此端口吗?
Daniel Ribeiro

我必须为设置正确的答案ssb,但是非常感谢您。我一定会进入这个港口!非常感谢!
丹尼尔·里贝罗

1
@DanielRibeiro啊,我明白了。我认为该方法在MonoGame中不存在,这就是为什么我最终使用这种方法。虽然欢呼。
ashes999 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.