Пример #1
0
		internal List<BackgroundLayer> DeserializeBackgroundLayers(JArray layers, Camera2D ownerCamera, BoundingRectangle ownerBounds)
		{
			List<BackgroundLayer> result = new List<BackgroundLayer>(layers.Count);

			foreach (var layerData in layers)
			{
				BackgroundLayer layer = new BackgroundLayer(ownerCamera, ownerBounds);

				string resourceName = (string)layerData["resourceName"];
				BackgroundScrollDirection direction = (BackgroundScrollDirection)(int)layerData["scrollDirection"];
				float scrollRate = (float)layerData["scrollRate"];

				layer.BackgroundTextureResourceName = resourceName;
				layer.ScrollDirection = direction;
				layer.ScrollRate = scrollRate;

				result.Add(layer);
			}

			return result;
		}
Пример #2
0
        /// <summary>
        ///   Returns a rectangle that can contain all the given positionables in
        ///   an enumerable.
        /// </summary>
        /// <param name="positionables">The enumerable containing the positionables.</param>
        /// <returns></returns>
        public static BoundingRectangle GetBoundsOfPositionables(this IEnumerable<IPositionable2> positionables)
        {
            if (!positionables.Any()) { return BoundingRectangle.NaN; }

            // so there's really no elegant initial value for result, except the
            // bounds of First()...
            var first = positionables.First();
            BoundingRectangle result = new BoundingRectangle(first.Position, first.Size + first.Position);

            foreach (var positionable in positionables.Skip(1)) // ...so we need to treat it specially
            {
                BoundingRectangle bounds = new BoundingRectangle(positionable.Position, positionable.Size + positionable.Position);

                if (bounds.Left < result.Left)
                {
                    result.Width += (bounds.X + result.X);
                    result.X = bounds.X;
                }
                else if (bounds.Right > result.Right)
                {
                    result.Width = (bounds.X + bounds.Width);
                }

                if (bounds.Top < result.Top)
                {
                    result.Height = (bounds.Y + result.Y);
                    result.Y = bounds.Y;
                }
                else if (bounds.Bottom > result.Bottom)
                {
                    result.Height = (bounds.Y + bounds.Height);
                }
            }

            return result;
        }
Пример #3
0
        /// <summary>
        ///   Resolves a collision between a rectangle and the sloped side of
        ///   this triangle.
        /// </summary>
        /// <param name="that">The rectangle to resolve.</param>
        /// <param name="intersection">
        ///   The intersection between the rectangle and the bounds of this triangle.
        /// </param>
        /// <returns>
        ///   The distance to move the rectangle by to resolve this collision.
        /// </returns>
        private Vector2 ResolveSlopeCollision(BoundingRectangle that, Vector2 intersection)
        {
            Vector2 topCenter = (HorizontalSlopedSide == HorizontalDirection.Left) ? that.TopRight : that.TopLeft;
            Vector2 bottomCenter = (HorizontalSlopedSide == HorizontalDirection.Left) ? that.BottomRight : that.BottomLeft;
            Vector2 pointOnSlope = GetPointOnSlope((HorizontalSlopedSide == HorizontalDirection.Left) ? that.Right : that.Left);

            if (pointOnSlope == Vector2.Zero)
            {
                return Vector2.Zero;
            }

            if (SlopedSides == RtSlopedSides.TopLeft || SlopedSides == RtSlopedSides.TopRight)
            {
                if (bottomCenter.Y > pointOnSlope.Y)
                {
                    // The bottom-center point is below the slope, resolution needed
                    return new Vector2(0f, -(bottomCenter.Y - pointOnSlope.Y));
                }
            }
            else if (SlopedSides == RtSlopedSides.BottomLeft || SlopedSides == RtSlopedSides.BottomRight)
            {
                if (topCenter.Y < pointOnSlope.Y)
                {
                    // The top-center point is above the slope, resolution needed
                    return new Vector2(0f, pointOnSlope.Y - topCenter.Y);
                }
            }

            return Vector2.Zero;
        }
Пример #4
0
 private bool IsSlopeCollision(BoundingRectangle rect, Vector2 intersect)
 {
     if (Math.Abs(intersect.X) < Math.Abs(intersect.Y))
     {
         if (VerticalSlopedSide == VerticalDirection.Up)
         {
             return intersect.Y < 0f;
         }
         else
         {
             return intersect.Y > 0f;
         }
     }
     else
     {
         if (HorizontalSlopedSide == HorizontalDirection.Left)
         {
             return intersect.X < 0f;
         }
         else if (HorizontalSlopedSide == HorizontalDirection.Right)
         {
             return intersect.X > 0f;
         }
     }
     return false;
 }
Пример #5
0
 /// <summary>
 ///   Determines if a given rectangle intersects this triangle.
 /// </summary>
 /// <param name="rect">The rectangle to check for intersection.</param>
 /// <returns>
 ///   True if any part of the rectangle intersects this right triangle,
 ///   false if otherwise.
 /// </returns>
 public bool Intersects(BoundingRectangle rect)
 {
     return rect.Intersects(this);
 }
Пример #6
0
 /// <summary>
 ///   Returns the depth of the intersection between this triangle and a
 ///   given rectangle.
 /// </summary>
 /// <param name="that">The given rectangle.</param>
 /// <returns>A vector representing the collision depth.</returns>
 public Vector2 GetIntersectionDepth(BoundingRectangle that)
 {
     return GetCollisionResolution(that);
 }
Пример #7
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="RightTriangle" /> class.
 /// </summary>
 /// <param name="bounds">
 ///   The rectangle that forms the bounds of the triangle.
 /// </param>
 /// <param name="slopedSides">Which sides of the triangle are sloped.</param>
 public RightTriangle(BoundingRectangle bounds, RtSlopedSides slopedSides)
 {
     Bounds = bounds;
     SlopedSides = slopedSides;
 }
Пример #8
0
        /// <summary>
        ///   Gets the minimum distance to move a given rectangle such that it
        ///   will no longer be intersecting this right triangle.
        /// </summary>
        /// <param name="rect">The rectangle to resolve.</param>
        /// <returns>
        ///   The minimum distance to move the rectangle, which can be directly
        ///   applied to the rectangle's position.
        /// </returns>
        /// <remarks>
        ///   This method resolves collision by first determining if the
        ///   bottom-center point (for TopLeft/TopRight triangles) or the
        ///   top-center point (for BottomLeft/BottomRight
        ///   triangles) is within the bounds. If it is, the method treats it as
        ///              a slope collision by checking if the point is between
        ///   the slope and the top. If it isn't, the collision is treated as a
        ///   collision between two rectangles.
        /// </remarks>
        public Vector2 GetCollisionResolution(BoundingRectangle rect)
        {
            // Vector2 rectCollisionPoint = (this.SlopedSides ==
            // RtSlopedSides.TopLeft || this.SlopedSides ==
            // RtSlopedSides.TopRight) ? rect.BottomCenter : rect.TopCenter;
            Vector2 rectCollisionPoint = Vector2.Zero;
            if (SlopedSides == RtSlopedSides.TopLeft) { rectCollisionPoint = rect.BottomRight; }
            else if (SlopedSides == RtSlopedSides.TopRight) { rectCollisionPoint = rect.BottomLeft; }
            else if (SlopedSides == RtSlopedSides.BottomLeft) { rectCollisionPoint = rect.TopRight; }
            else if (SlopedSides == RtSlopedSides.BottomRight) { rectCollisionPoint = rect.TopLeft; }

            if (!Bounds.IntersectsIncludingEdges(rectCollisionPoint))
            {
                return Bounds.GetCollisionResolution(rect);
            }
            else
            {
                return ResolveSlopeCollision(rect, Bounds.GetCollisionResolution(rect));
            }
        }
Пример #9
0
 /// <summary>
 ///   Returns a value indicating whether a bounding rectangle is entirely
 ///   contained within this rectangle.
 /// </summary>
 /// <param name="that">The other rectangle.</param>
 /// <returns>
 ///   True if the other rectangle is entirely contained within this one,
 ///   false if otherwise.
 /// </returns>
 public bool Within(BoundingRectangle that)
 {
     return (that.Left >= Left) && (that.Right <= Right) && (that.Top >= Top) && (that.Bottom <= Bottom);
 }
Пример #10
0
        /// <summary>
        ///   Returns a value indicating whether another rectangle intersects or
        ///   is tangent to this one.
        /// </summary>
        /// <param name="that">The other rectangle.</param>
        /// <returns>
        ///   True if the other rectangle intersects or is tangent to this one,
        ///   false if otherwise.
        /// </returns>
        public bool IntersectsIncludingEdges(BoundingRectangle that)
        {
            if (that.Right < Left || that.Left > Right)
            {
                return false;
            }
            else if (that.Bottom < Top || that.Top > Bottom)
            {
                return false;
            }

            return true;
        }
Пример #11
0
        /// <summary>
        ///   Determines if a given rectangle is intersecting this rectangle.
        /// </summary>
        /// <param name="that">The rectangle to check.</param>
        /// <returns>
        ///   True if any part of the other rectangle is intersecting this
        ///   rectangle, false if otherwise.
        /// </returns>
        public bool Intersects(BoundingRectangle that)
        {
            if (that.Right <= Left || that.Left >= Right)
            {
                return false;
            }
            else if (that.Bottom <= Top || that.Top >= Bottom)
            {
                return false;
            }

            return true;
        }
Пример #12
0
        /// <summary>
        ///   Returns the intersection depth between a given rectangle and this one.
        /// </summary>
        /// <param name="that">The rectangle to check.</param>
        /// <returns>
        ///   The intersection depth between the other rectangle and this one. If
        ///   the rectangles aren't intersecting, a vector with NaN components is returned.
        /// </returns>
        /// <remarks>
        ///   This method determines the sign of either component of the result
        ///   by determining the "direction" of the intersection - for example,
        ///   if the right edge of the other rectangle is to the left of the
        ///   center of this rectangle, the "direction" is to the left, and since
        ///   left is negative X, the resulting X component will be negative.
        /// </remarks>
        public Vector2 GetIntersectionDepth(BoundingRectangle that)
        {
            IntersectionCallCount++;
            Vector2 result = new Vector2(float.NaN);

            Vector2 thisCenter = Center;
            Vector2 thatCenter = that.Center;

            Vector2 thisHalfSize = Size / 2f;
            Vector2 thatHalfSize = that.Size / 2f;
            Vector2 combinedSizes = thisHalfSize + thatHalfSize;

            // X-axis checks
            float xDistanceBetweenCenters = thatCenter.X - thisCenter.X;
            float absXDistance = Math.Abs(xDistanceBetweenCenters);
            float signXDistance = (xDistanceBetweenCenters >= 0f) ? 1f : -1f;
            if (absXDistance < combinedSizes.X)
            {
                result.X = signXDistance * (combinedSizes.X - Math.Abs(xDistanceBetweenCenters));
            }

            // Y-axis checks
            float yDistanceBetweenCenters = thatCenter.Y - thisCenter.Y;
            float absYDistance = Math.Abs(yDistanceBetweenCenters);
            float signYDistance = (yDistanceBetweenCenters >= 0f) ? 1f : -1f;
            if (absYDistance < combinedSizes.Y)
            {
                result.Y = signYDistance * (combinedSizes.Y - Math.Abs(yDistanceBetweenCenters));
            }

            return result;

            // WYLO: We're returning wrong results here, or at least results that
            //       we didn't get before. If a sprite and tile have the same X
            // position and same width, this method returns 0 for X, where the
            // old one returned 16. Maybe we can apply the sign(a)*(b-|a|) to
            // Right and Left instead? Do some math and find out.
        }
Пример #13
0
        /// <summary>
        ///   Returns the distance to move a given rectangle in order to properly
        ///   resolve a collision.
        /// </summary>
        /// <param name="that">The rectangle to check.</param>
        /// <returns>
        ///   A value that can be applied to the position of the rectangle to
        ///   move it the minimum distance such that it won't be intersecting
        ///   this one.
        /// </returns>
        /// <remarks>
        ///   Internally, this method uses the GetIntersectionDepth() method to
        ///   determine the intersection depth. It then determines which of the
        ///   two axes has the smallest absolute value and zeroes out the other.
        ///   This way of collision resolution is called the "shallowest edge"
        ///   method, and it allows quick determination of which axis to resolve along.
        /// </remarks>
        public Vector2 GetCollisionResolution(BoundingRectangle that)
        {
            Vector2 intersection = GetIntersectionDepth(that);

            return GetCollisionResolution(intersection);
        }
Пример #14
0
 /// <summary>
 ///   Gets a position to place another rectangle at such that both this
 ///   and that's Center lines are equal.
 /// </summary>
 /// <param name="that">The rectangle to align.</param>
 /// <returns>A position to move the rectangle to.</returns>
 public Vector2 GetCenterAlignedInColumnPosition(BoundingRectangle that)
 {
     float halfWidth = that.Width / 2f;
     return new Vector2(Center.X - halfWidth, that.Y);
 }
Пример #15
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="BackgroundLayer" /> class.
 /// </summary>
 /// <param name="ownerCamera">
 ///   The camera of the section that contains this layer.
 /// </param>
 /// <param name="sectionBounds">
 ///   The bounds of the section that contains this layer.
 /// </param>
 public BackgroundLayer(Camera2D ownerCamera, BoundingRectangle sectionBounds)
 {
     camera = ownerCamera;
     this.sectionBounds = sectionBounds;
 }