Esempio n. 1
0
        // Detects any vector that is withing the vision range and returns it as a list
        private List <Vector2> Vision(List <Collider> colliders)
        {
            List <Vector2> visibleVectors = new List <Vector2>();

            // Create the vision vector
            ahead = colliderPosition + Vector2.Normalize(velocity) * visionLength;

            // Create an arc of 'detector points'
            int            degrees        = (int)MathHelper.ToDegrees(visionAngle);
            int            stepSize       = 15;
            List <Vector2> detectorPoints = new List <Vector2>();

            for (int i = -degrees; i < degrees; i += stepSize)
            {
                Vector2 point = Helper.RotateAroundOrigin(ahead, colliderPosition, MathHelper.ToRadians(i));
                detectorPoints.Add(point);
                DrawLater(() => spriteBatch.DrawPoint(point, Color.LightBlue, 5f));
            }

            // Go through every collider in this world
            foreach (Collider collider in colliders)
            {
                if (collider.Equals(this))
                {
                    continue; // You shouldn't be able to 'see' yourself
                }

                DrawLater(() => spriteBatch.DrawCircle(colliderPosition, visionLength, 180, Color.DarkBlue)); // DEBUG: How far we can see around us
                if (!CircleCircleIntersect(colliderPosition, visionLength, collider.colliderPosition, collider.colliderRadius))
                {
                    continue; // Collider is not in range of our vision 'collider'
                }

                // Check if a detector point intersects with the collider
                // If so, we can add this detector point to the list of visible vectors
                // TODO: It is not really a visible vector, you'd expect the collider to get added to the list... Maybe refactor this..
                foreach (Vector2 detector in detectorPoints)
                {
                    DrawLater(() => spriteBatch.DrawLine(colliderPosition, detector, Color.LightBlue)); // DEBUG: Draw a line to all detector points
                    CircleLineCollisionResult result = new CircleLineCollisionResult();
                    CircleLineCollide(collider.colliderPosition, collider.colliderRadius, colliderPosition, detector, ref result);
                    if (result.Collision)
                    {
                        DrawLater(() => spriteBatch.DrawPoint(detector, Color.Red, 5f)); // DEBUG: Show the detector point as red if he detects something
                        visibleVectors.Add(detector);
                    }
                }
            }

            return(visibleVectors);
        }
Esempio n. 2
0
        /// <summary>
        /// Determines if a circle and line segment intersect, and if so, how they do.
        /// </summary>
        /// <param name="position">The center of the circle.</param>
        /// <param name="radius">The radius of the circle.</param>
        /// <param name="lineStart">The first point on the line segment.</param>
        /// <param name="lineEnd">The second point on the line segment.</param>
        /// <param name="result">The result data for the collision.</param>
        /// <returns>True if a collision occurs, provided for convenience.</returns>
        public static bool CircleLineCollide(Vector2 center, float radius,
                                             Vector2 lineStart, Vector2 lineEnd, ref CircleLineCollisionResult result)
        {
            Vector2 AC  = center - lineStart;
            Vector2 AB  = lineEnd - lineStart;
            float   ab2 = AB.LengthSquared();

            if (ab2 <= 0f)
            {
                return(false);
            }
            float acab = Vector2.Dot(AC, AB);
            float t    = acab / ab2;

            if (t < 0.0f)
            {
                t = 0.0f;
            }
            else if (t > 1.0f)
            {
                t = 1.0f;
            }

            result.Point  = lineStart + t * AB;
            result.Normal = center - result.Point;

            float h2 = result.Normal.LengthSquared();
            float r2 = radius * radius;

            if (h2 > r2)
            {
                result.Collision = false;
            }
            else
            {
                result.Normal.Normalize();
                result.Distance  = (radius - (center - result.Point).Length());
                result.Collision = true;
            }

            return(result.Collision);
        }
        /// <summary>
        /// Determines if a circle and line segment intersect, and if so, how they do.
        /// </summary>
        /// <param name="center">The center of the circle.</param>
        /// <param name="radius">The radius of the circle.</param>
        /// <param name="rectangle">The rectangle.</param>
        /// <param name="result">The result data for the collision.</param>
        /// <returns>True if a collision occurs, provided for convenience.</returns>
        public static bool CircleRectangleCollide(Vector2 center, float radius,
                                                  Rectangle rectangle, ref CircleLineCollisionResult result)
        {
            float xVal = center.X;

            if (xVal < rectangle.Left)
            {
                xVal = rectangle.Left;
            }
            if (xVal > rectangle.Right)
            {
                xVal = rectangle.Right;
            }

            float yVal = center.Y;

            if (yVal < rectangle.Top)
            {
                yVal = rectangle.Top;
            }
            if (yVal > rectangle.Bottom)
            {
                yVal = rectangle.Bottom;
            }

            Vector2 direction = new Vector2(center.X - xVal, center.Y - yVal);
            float   distance  = direction.Length();

            if ((distance > 0) && (distance < radius))
            {
                result.Collision = true;
                result.Distance  = radius - distance;
                result.Normal    = Vector2.Normalize(direction);
                result.Point     = new Vector2(xVal, yVal);
            }
            else
            {
                result.Collision = false;
            }

            return(result.Collision);
        }
Esempio n. 4
0
        /// <summary>
        /// Determines if a circle and line segment intersect, and if so, how they do.
        /// </summary>
        /// <param name="center">The center of the circle.</param>
        /// <param name="radius">The radius of the circle.</param>
        /// <param name="lineStart">The first point on the line segment.</param>
        /// <param name="lineEnd">The second point on the line segment.</param>
        /// <param name="result">The result data for the collision.</param>
        /// <returns>True if a collision occurs, provided for convenience.</returns>
        public static bool CircleLineCollide(Vector2 center, float radius,
            Vector2 lineStart, Vector2 lineEnd, ref CircleLineCollisionResult result)
        {
            Vector2 AC = center - lineStart;
            Vector2 AB = lineEnd - lineStart;
            float ab2 = AB.LengthSquared();
            if (ab2 <= 0f)
            {
                return false;
            }
            float acab = Vector2.Dot(AC, AB);
            float t = acab / ab2;

            if (t < 0.0f)
                t = 0.0f;
            else if (t > 1.0f)
                t = 1.0f;

            result.Point = lineStart + t * AB;
            result.Normal = center - result.Point;

            float h2 = result.Normal.LengthSquared();
            float r2 = radius * radius;

            if ((h2 > 0) && (h2 <= r2))
            {
                result.Normal.Normalize();
                result.Distance = (radius - (center - result.Point).Length());
                result.Collision = true;
            }
            else
            {
                result.Collision = false;
            }

            return result.Collision;
        }
Esempio n. 5
0
        /// <summary>
        /// Determines if a circle and a rectangle intersect, and if so, how they do.
        /// </summary>
        /// <param name="center">The center of the circle.</param>
        /// <param name="radius">The radius of the circle.</param>
        /// <param name="rectangle">The rectangle.</param>
        /// <param name="result">The result data for the collision.</param>
        /// <returns>True if a collision occurs, provided for convenience.</returns>
        public static bool CircleRectangleCollide(Vector2 center, float radius,
            Rectangle rectangle, ref CircleLineCollisionResult result)
        {
            float xVal = center.X;
            if (xVal < rectangle.Left) xVal = rectangle.Left;
            if (xVal > rectangle.Right) xVal = rectangle.Right;

            float yVal = center.Y;
            if (yVal < rectangle.Top) yVal = rectangle.Top;
            if (yVal > rectangle.Bottom) yVal = rectangle.Bottom;

            Vector2 direction = new Vector2(center.X - xVal, center.Y - yVal);
            float distance = direction.Length();

            if ((distance > 0) && (distance < radius))
            {
                result.Collision = true;
                result.Distance = radius - distance;
                result.Normal = Vector2.Normalize(direction);
                result.Point = new Vector2(xVal, yVal);
            }
            else
            {
                result.Collision = false;
            }

            return result.Collision;
        }
Esempio n. 6
0
 /// <summary>
 /// Determines if a circle and a rectangle interset, and if so, how they do.
 /// </summary>
 /// <param name="center">The center of the circle.</param>
 /// <param name="radius">The radius of the circle.</param>
 /// <param name="rectangleCorners">Corner coordinates of the rectangle.</param>
 /// <param name="result">The result data for the collision.</param>
 /// <returns>True if a collision occurs, provided for convenience.</returns>
 public static bool CircleRectangleCollide(Vector2 center, float radius,
     Vector2[] rectangleCorners, ref CircleLineCollisionResult result)
 {
     return false;
 }