Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a Breakout game in which, at some point, I detect the collision between the ball and the paddle with something like this:

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

Is there any way I can get the exact coordinates of the collision, or any details about it, with the current XNA API?

I thought of doing some basic calculations, such as comparing the exact coordinates of each object on the moment of the collision. It would look something like this:

// 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

But I'm not sure this is the correct way to do it.

Do you guys have any tips on maybe an engine I might have to use to achieve that? Or even good coding practices using this method?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

XNA's rectangles are pretty limited. The Rectangle.Intersects() method only returns a boolean result, so you'll need to do more tests yourself if you want details. You can, however, use the Rectangle.Intersect(Rectangle, Rectangle) method to get the rectangle where the two overlap. That will give you some information on depth and location, at least.

share|improve this answer
    
Is this get the rectangle where the two overlap functionallity available on the XNA API or I have to download some extra stuff, like the Platformer Starter Kit? –  Daniel Ribeiro Dec 19 '12 at 12:20
1  
Which method is this? I don't recall that XNA 4.0 supports Rectangle Rectangle.Intersects(...). –  ashes999 Dec 19 '12 at 12:25
    
Someone gave me the right at stackoverflow: msdn.microsoft.com/en-us/library/… –  Daniel Ribeiro Dec 19 '12 at 12:55
    
Ok, with the returned Rectangle, how can I check the position of the paddle that got collided by the ball? –  Daniel Ribeiro Dec 19 '12 at 21:59
    
If you know that the paddle and ball are intersecting then you use the location information of the paddle rectangle that you checked in the first place, i.e. rectangle.X or rectangle.Y or whatever you want to access. –  ssb Dec 20 '12 at 0:00

Update: If you're using MonoGame, then as of 3.0 beta, Rectangle Rectangle.Intersect(rectangle, rectangle) doesn't exist. You can use the below code from the XNA Platformer kit instead.


You can download the XNA Platformer Starter Kit (ported to Windows 7). It ships with a helper extension method that returns a rectangle describing the intersection of two rectangles:

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);
        }
}
share|improve this answer
    
Thank you very much for this link. May I ask you why did you need to use a modified version? Is that port official? –  Daniel Ribeiro Dec 19 '12 at 12:21
    
@DanielRibeiro I checked my history and apparently I didn't modify it after all. The port is unofficial; I simply couldn't find the original. It works with MonoGame/C#, which was good enough for me. –  ashes999 Dec 19 '12 at 12:24
    
But there is an original port, right? Isn't this supposed to be such a simple feature? Anyways, I'm not using MonoGame, just XNA. Would you still recommend me to use this port? –  Daniel Ribeiro Dec 19 '12 at 12:27
    
I had to set the correct answer to ssb, but thank you very much for this. I'll for sure get into this port! Many thanks! –  Daniel Ribeiro Dec 19 '12 at 12:56
1  
@DanielRibeiro ah, I see. I think that method doesn't exist in MonoGame, which is why I ended up using this approach. Cheers though. –  ashes999 Dec 19 '12 at 14:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.