Rectangle.Intersects()から衝突の詳細を取得する


9

私はある時点で、次のようなものでボールとパドルの衝突を検出するブレイクアウトゲームを持っています。

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

しかし、これが正しい方法かどうかはわかりません。

皆さんは私がそれを達成するために使用しなければならないかもしれないエンジンについて何かヒントがありますか?または、この方法を使用した優れたコーディング慣行ですか?

回答:


8

XNAの長方形はかなり制限されています。このRectangle.Intersects()メソッドはブール結果のみを返すため、詳細が必要な場合は、さらに多くのテストを自分で行う必要があります。ただし、このRectangle.Intersect(Rectangle, Rectangle)メソッドを使用して、2つが重なり合う長方形を取得できます。これにより、少なくとも深さと位置に関する情報が得られます。


このget the rectangle where the two overlap機能はで利用できますXNA APIか、またはのように追加のものをダウンロードする必要がありPlatformer Starter Kitますか?
Daniel Ribeiro

1
これはどの方法ですか?XNA 4.0がをサポートしていることを思い出しませんRectangle Rectangle.Intersects(...)
ashes999

:誰かが私のstackoverflowで右与えたmsdn.microsoft.com/en-us/library/...
ダニエル・リベイロを

返されたRectangleで、ボールが衝突したパドルの位置を確認するにはどうすればよいですか?
Daniel Ribeiro

あなたはパドルとボールが交差していることを知っているなら、あなたは、最初の場所でチェックすなわちことパドル矩形の位置情報を使用rectangle.Xまたはrectangle.Yまたはものは何でもあなたがアクセスしたいが。
ssb

4

更新: MonoGameを使用している場合、3.0ベータ版以降Rectangle Rectangle.Intersect(rectangle, rectangle)は存在しません。代わりに、XNA Platformerキットの以下のコードを使用できます。


XNA Platformer Starter Kit(Windows 7に移植)をダウンロードできます。2つの長方形の交差部分を表す長方形を返すヘルパー拡張メソッドが同梱されています。

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がありましたが、これをありがとうございました。きっとこのポートに入ります!どうもありがとう!
Daniel Ribeiro

1
@DanielRibeiroああ、なるほど。その方法はMonoGameには存在しないと思うので、このアプローチを使用することになりました。乾杯。
ashes999
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.