Esempio n. 1
0
        /// <summary>
        /// Handles the collisions.
        /// </summary>
        /// <param name="direction">The direction.</param>
        /// <param name="source">The source.</param>
        public static void HandleCollisions(Direction direction, IMovingCollidable source)
        {
            // Safety-check the singleton
            if (_collisionManager == null)
            {
                return;
            }

            if (source.IsActive)
            {
                var sourcePreviousBoundingBox = source.PreviousBoundingBox;

                // Loop through the possible targets
                foreach (var target in _collisionManager._collisionTree.Retrieve(source))
                {
                    // Initialize variables
                    var sourceBoundingBox = source.BoundingBox;
                    var targetBoundingBox = target.BoundingBox;

                    // Determine if source and target currently overlap (e.g. a collision has occurred
                    if ((source != target) && sourceBoundingBox.Intersects(targetBoundingBox))
                    {
                        // Initialize the variables
                        var collisionOffset = Vector2.Zero;
                        var sourceDirection = Direction.None;
                        var targetDirection = Direction.None;

                        // Evaluate only in the directions specfied
                        if (direction.HasFlag(Direction.Top))
                        {
                            // Source Top
                            if (source.PreviousBoundingBox.Top >= targetBoundingBox.Bottom)
                            {
                                collisionOffset  = new Vector2(collisionOffset.X, targetBoundingBox.Bottom - sourceBoundingBox.Top);
                                sourceDirection |= Direction.Top;
                                targetDirection |= Direction.Bottom;
                            }
                        }

                        if (direction.HasFlag(Direction.Bottom))
                        {
                            // Source Bottom
                            if (source.PreviousBoundingBox.Bottom <= targetBoundingBox.Top)
                            {
                                collisionOffset  = new Vector2(collisionOffset.X, targetBoundingBox.Top - sourceBoundingBox.Bottom);
                                sourceDirection |= Direction.Bottom;
                                targetDirection |= Direction.Top;
                            }
                        }

                        if (direction.HasFlag(Direction.Left))
                        {
                            // Source Left
                            if (source.PreviousBoundingBox.Left >= targetBoundingBox.Right)
                            {
                                collisionOffset  = new Vector2(targetBoundingBox.Right - sourceBoundingBox.Left, collisionOffset.Y);
                                sourceDirection |= Direction.Left;
                                targetDirection |= Direction.Right;
                            }
                        }

                        if (direction.HasFlag(Direction.Right))
                        {
                            // Source Right
                            if (source.PreviousBoundingBox.Right <= targetBoundingBox.Left)
                            {
                                collisionOffset  = new Vector2(targetBoundingBox.Left - sourceBoundingBox.Right, collisionOffset.Y);
                                sourceDirection |= Direction.Right;
                                targetDirection |= Direction.Left;
                            }
                        }

                        // Handle the collision if one occurred
                        if (sourceDirection != Direction.None)
                        {
                            // Tell the source and target about the collision
                            source.HandleCollisions(new CollisionInfo(source, target, sourceDirection, collisionOffset));
                            target.HandleCollisions(new CollisionInfo(target, source, targetDirection, -collisionOffset));
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        private static void TryCorrectPosition(Rectangle tryPosition, TFirst moveableObject, ICollidable collidable, IMovingCollidable movingCollidable, bool correctX, bool correctY, bool correctPastOriginal = false)
        {
            float newX = tryPosition.Center.X;
            float newY = tryPosition.Center.Y;

            float deltaX = 0, deltaY = 0;

            if (correctPastOriginal)
            {
                newX = newX.Approach(moveableObject.Motion.FrameStartPosition.Center.X, 1);
                newY = newY.Approach(moveableObject.Motion.FrameStartPosition.Center.Y, 1);

                deltaX = (newX - moveableObject.Motion.FrameStartPosition.Center.X).Unit();
                deltaY = (newY - moveableObject.Motion.FrameStartPosition.Center.Y).Unit();

                if (deltaX == 0 && deltaY == 0)
                {
                    if (movingCollidable == null)
                    {
                        deltaY = -1;
                    }
                    else
                    {
                        deltaY = (newY - movingCollidable.Position.Center.Y).Unit();
                    }
                }
            }
            while (collidable.DetectCollision(tryPosition, true))
            {
                float newX2 = newX, newY2 = newY;

                if (correctPastOriginal)
                {
                    newX2 = newX + deltaX;
                    newY2 = newY + deltaY;
                }
                else
                {
                    if (correctX)
                    {
                        newX2 = newX.Approach(moveableObject.Motion.FrameStartPosition.Center.X, 1);
                    }

                    if (correctY)
                    {
                        newY2 = newY.Approach(moveableObject.Motion.FrameStartPosition.Center.Y, 1);
                    }
                }

                if (newX2 == newX && newY2 == newY)
                {
                    newX = newX2;
                    newY = newY2;
                    break;
                }
                else
                {
                    newX = newX2;
                    newY = newY2;
                }

                tryPosition.Center = new Vector2(newX, newY);
            }
        }