Inheritance: ICollidable
Beispiel #1
0
        private static void HandleCollision(CollisionCircle circle1, CollisionCircle circle2)
        {
            if (circle1.IsStatic && circle2.IsStatic)
            {
                return;
            }

            Vector2 d        = circle1.Center - circle2.Center;
            float   distance = d.Length();

            // If two circles collide
            if (circle1.Radius + circle2.Radius > distance)
            {
                if (distance == 0)
                {
                    d.X = r.Next(-200, 201);
                    d.Y = r.Next(-200, 201);
                    if (d != Vector2.Zero)
                    {
                        d.Normalize();
                    }
                }
                else
                {
                    d /= distance;
                }

                // Static objects do not move, so only move back the non-static one
                if (circle1.IsStatic)
                {
                    d *= -1;
                    float distToPush = circle1.Radius + circle2.Radius - distance + OFFSET;
                    circle2.Center += distToPush * d;
                }
                else if (circle2.IsStatic)
                {
                    Vector2 direction  = d / distance;
                    float   distToPush = circle1.Radius + circle2.Radius - distance + OFFSET;
                    circle1.Center += distToPush * d;
                }
                // If both objects are non-static, move them both back evenly
                else
                {
                    float distToPush = (circle1.Radius + circle2.Radius - distance) / 2 + OFFSET;
                    circle1.Center += distToPush * d;
                    circle2.Center -= distToPush * d;
                }
            }
        }
Beispiel #2
0
        private static void HandleCollision(CollisionCircle circle, CollisionRect rect)
        {
            if(circle.IsStatic && rect.IsStatic)
                return;

            // Reference: stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection/402010#402010
            Vector2 d = circle.Center - rect.Center;
            d = new Vector2(Math.Abs(d.X), Math.Abs(d.Y));
            Vector2 cd = new Vector2(d.X - rect.Width * 0.5f, d.Y - rect.Depth * 0.5f);
            float cornerDistSqr = cd.LengthSquared();

            // If circle and rectangle collide
            if(d.X <= rect.Width / 2 + circle.Radius && d.Y <= rect.Depth / 2 + circle.Radius
                || cornerDistSqr <= circle.Radius * circle.Radius) {
                // If circle and rectangle centers completely overlap,
                // slightly move one of the object's center so they don't completely overlap
                if(d.Length() == 0) {
                    d.X = r.Next(-200, 201);
                    d.Y = r.Next(-200, 201);
                    if(d != Vector2.Zero) {
                        d.Normalize();
                        d *= 0.1f;
                    }
                    if(circle.IsStatic)
                        rect.Center += d;
                    else
                        circle.Center += d;
                    HandleCollision(circle, rect);
                }

                // Create a collision boundary around the rectangle, in which collision occurs
                float top = rect.Center.Y + rect.Depth / 2 + circle.Radius;
                float bottom = rect.Center.Y - rect.Depth / 2 - circle.Radius;
                float left = rect.Center.X - rect.Width / 2 - circle.Radius;
                float right = rect.Center.X + rect.Width / 2 + circle.Radius;
                float distToTop = Math.Abs(circle.Center.Y - top);
                float distToBottom = Math.Abs(circle.Center.Y - bottom);
                float distToLeft = Math.Abs(circle.Center.X - left);
                float distToRight = Math.Abs(circle.Center.X - right);

                // Choose the closest distance to the collision boundary as the pushing direction
                Vector2 pushAmount = new Vector2(); // How much should be pushed relative to circle
                float min = Math.Min(Math.Min(Math.Min(distToTop, distToBottom), distToLeft), distToRight);
                pushAmount.Y += min == distToTop ? distToTop + OFFSET : 0;
                pushAmount.Y += min == distToBottom ? -distToBottom - OFFSET : 0;
                pushAmount.X += min == distToLeft ? -distToLeft - OFFSET : 0;
                pushAmount.X += min == distToRight ? distToRight + OFFSET : 0;

                // Only move the non-static object
                if(rect.IsStatic)
                    circle.Center += pushAmount;
                else if(circle.IsStatic)
                    rect.Center -= pushAmount;
                else {
                    circle.Center += pushAmount / 2;
                    rect.Center -= pushAmount / 2;
                }

            }
        }
Beispiel #3
0
        private static void HandleCollision(CollisionCircle circle1, CollisionCircle circle2)
        {
            if(circle1.IsStatic && circle2.IsStatic) return;

            Vector2 d = circle1.Center - circle2.Center;
            float distance = d.Length();

            // If two circles collide
            if(circle1.Radius + circle2.Radius > distance) {
                if(distance == 0) {
                    d.X = r.Next(-200, 201);
                    d.Y = r.Next(-200, 201);
                    if(d != Vector2.Zero)
                        d.Normalize();
                }
                else {
                    d /= distance;
                }

                // Static objects do not move, so only move back the non-static one
                if(circle1.IsStatic) {
                    d *= -1;
                    float distToPush = circle1.Radius + circle2.Radius - distance + OFFSET;
                    circle2.Center += distToPush * d;
                }
                else if(circle2.IsStatic) {
                    Vector2 direction = d / distance;
                    float distToPush = circle1.Radius + circle2.Radius - distance + OFFSET;
                    circle1.Center += distToPush * d;
                }
                // If both objects are non-static, move them both back evenly
                else {
                    float distToPush = (circle1.Radius + circle2.Radius - distance) / 2 + OFFSET;
                    circle1.Center += distToPush * d;
                    circle2.Center -= distToPush * d;
                }
            }
        }
Beispiel #4
0
        private static void HandleCollision(CollisionCircle circle, CollisionRect rect)
        {
            if (circle.IsStatic && rect.IsStatic)
            {
                return;
            }

            // Reference: stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection/402010#402010
            Vector2 d = circle.Center - rect.Center;

            d = new Vector2(Math.Abs(d.X), Math.Abs(d.Y));
            Vector2 cd            = new Vector2(d.X - rect.Width * 0.5f, d.Y - rect.Depth * 0.5f);
            float   cornerDistSqr = cd.LengthSquared();

            // If circle and rectangle collide
            if (d.X <= rect.Width / 2 + circle.Radius && d.Y <= rect.Depth / 2 + circle.Radius ||
                cornerDistSqr <= circle.Radius * circle.Radius)
            {
                // If circle and rectangle centers completely overlap,
                // slightly move one of the object's center so they don't completely overlap
                if (d.Length() == 0)
                {
                    d.X = r.Next(-200, 201);
                    d.Y = r.Next(-200, 201);
                    if (d != Vector2.Zero)
                    {
                        d.Normalize();
                        d *= 0.1f;
                    }
                    if (circle.IsStatic)
                    {
                        rect.Center += d;
                    }
                    else
                    {
                        circle.Center += d;
                    }
                    HandleCollision(circle, rect);
                }

                // Create a collision boundary around the rectangle, in which collision occurs
                float top          = rect.Center.Y + rect.Depth / 2 + circle.Radius;
                float bottom       = rect.Center.Y - rect.Depth / 2 - circle.Radius;
                float left         = rect.Center.X - rect.Width / 2 - circle.Radius;
                float right        = rect.Center.X + rect.Width / 2 + circle.Radius;
                float distToTop    = Math.Abs(circle.Center.Y - top);
                float distToBottom = Math.Abs(circle.Center.Y - bottom);
                float distToLeft   = Math.Abs(circle.Center.X - left);
                float distToRight  = Math.Abs(circle.Center.X - right);

                // Choose the closest distance to the collision boundary as the pushing direction
                Vector2 pushAmount = new Vector2(); // How much should be pushed relative to circle
                float   min        = Math.Min(Math.Min(Math.Min(distToTop, distToBottom), distToLeft), distToRight);
                pushAmount.Y += min == distToTop ? distToTop + OFFSET : 0;
                pushAmount.Y += min == distToBottom ? -distToBottom - OFFSET : 0;
                pushAmount.X += min == distToLeft ? -distToLeft - OFFSET : 0;
                pushAmount.X += min == distToRight ? distToRight + OFFSET : 0;

                // Only move the non-static object
                if (rect.IsStatic)
                {
                    circle.Center += pushAmount;
                }
                else if (circle.IsStatic)
                {
                    rect.Center -= pushAmount;
                }
                else
                {
                    circle.Center += pushAmount / 2;
                    rect.Center   -= pushAmount / 2;
                }
            }
        }