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