Rectangle에서 충돌 세부 정보를 가져옵니다.


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)방법을 사용 하여 두 부분이 겹치는 사각형을 얻을 수 있습니다 . 그것은 적어도 당신에게 깊이와 위치에 대한 정보를 줄 것입니다.


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/…
Daniel Ribeiro

자, 반환 된 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로 포팅)를 다운로드 할 수 있습니다 . 두 사각형의 교차점을 설명하는 사각형을 반환하는 도우미 확장 메서드와 함께 제공됩니다.

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 나는 내 역사를 확인했고 결국 그것을 수정하지 않은 것 같습니다. 항구는 비공식적이다. 원본을 찾을 수 없었습니다. 그것은 모노 게임 / C #과 함께 작동합니다.
ashes999

그러나 원래 포트가 있습니다. 이것이 간단한 기능이 아닌가? 어쨌든, 나는 MonoGame을 사용하지 않고 XNA 만 사용합니다. 여전히이 포트를 사용하도록 권장 하시겠습니까?
Daniel Ribeiro

에 정답을 설정해야 ssb했지만 매우 감사합니다. 나는 확실히이 포트에 들어갈 것이다! 많은 감사합니다!
Daniel Ribeiro

1
@DanielRibeiro 아, 알겠습니다. MonoGame에는 메소드가 존재하지 않는다고 생각하기 때문에이 접근법을 사용했습니다. 그래도 건배.
ashes999
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.