Çarpışma ayrıntılarını Rectangle.Intersects () öğesinden alın


9

Bir noktada, top ve raket arasındaki çarpışmayı böyle bir şeyle tespit ettiğim bir Breakout oyunum var:

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

Çarpışmanın kesin koordinatlarını veya bununla ilgili herhangi bir ayrıntıyı akımla almanın herhangi bir yolu var mı XNA API?

Çarpışma anında her bir nesnenin kesin koordinatlarını karşılaştırmak gibi bazı temel hesaplamalar yapmayı düşündüm. Bunun gibi bir şey olurdu:

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

Ama bunun doğru yolu olduğundan emin değilim.

Belki bunu başarmak için kullanmam gereken bir motor hakkında ipucunuz var mı? Ya da bu yöntemi kullanarak iyi kodlama uygulamaları mı?

Yanıtlar:


8

XNA'nın dikdörtgenleri oldukça sınırlıdır. Rectangle.Intersects()Eğer ayrıntıları istiyorsanız daha Testlerin kendiniz yapmak gerekir böylece yöntemi sadece bir boolean sonuç döndürür. Bununla birlikte, Rectangle.Intersect(Rectangle, Rectangle)iki üst üste binen dikdörtgeni elde etmek için yöntemi kullanabilirsiniz . Bu size en azından derinlik ve konum hakkında bilgi verecektir.


Bu get the rectangle where the two overlapişlevsellik kullanılabilir mi XNA APIveya gibi bazı ekstra şeyler indirmek zorunda Platformer Starter Kitmıyım?
Daniel Ribeiro

1
Bu hangi yöntem? XNA 4.0'ın desteklediğini hatırlamıyorum Rectangle Rectangle.Intersects(...).
ashes999

Birisi bana stackoverflow'da hak verdi: msdn.microsoft.com/en-us/library/…
Daniel Ribeiro

Tamam, geri döndürülen Dikdörtgen ile, topun çarptığı raketin konumunu nasıl kontrol edebilirim?
Daniel Ribeiro

Kürek ve topun kesiştiğini biliyorsanız, ilk etapta kontrol ettiğiniz kürek dikdörtgeninin konum bilgilerini, yani rectangle.Xveya rectangle.Yerişmek istediğiniz her şeyi kullanırsınız.
ssb

4

Güncelleme: MonoGame kullanıyorsanız, 3.0 beta itibariyle Rectangle Rectangle.Intersect(rectangle, rectangle)mevcut değildir. Bunun yerine XNA Platformer kitinden aşağıdaki kodu kullanabilirsiniz.


XNA Platformer Başlangıç ​​Seti'ni ( Windows 7'ye taşındı ) indirebilirsiniz . İki dikdörtgenin kesişimini açıklayan bir dikdörtgen döndüren bir yardımcı genişletme yöntemiyle birlikte gönderilir:

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);
        }
}

Bu bağlantı için çok teşekkür ederim. Neden değiştirilmiş bir sürümü kullanmanız gerektiğini sorabilir miyim? Bu liman resmi mi?
Daniel Ribeiro

@DanielRibeiro Geçmişimi kontrol ettim ve görünüşe göre değiştirmedim. Liman gayri resmi; Orijinali bulamadım. Benim için yeterince iyi olan MonoGame / C # ile çalışır.
ashes999

Ama orijinal bir liman var, değil mi? Bunun bu kadar basit bir özellik olması gerekmiyor mu? Her neyse, MonoGame kullanmıyorum, sadece XNA. Yine de bu bağlantı noktasını kullanmamı önerir misin?
Daniel Ribeiro

Doğru cevabı vermeliydim ssb, ama bunun için çok teşekkür ederim. Kesinlikle bu limana gireceğim! Çok teşekkürler!
Daniel Ribeiro

1
@DanielRibeiro ah, anlıyorum. Bu yöntemin MonoGame'de mevcut olmadığını düşünüyorum, bu yüzden bu yaklaşımı kullandım. Şerefe.
ashes999
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.