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.