Exemple #1
0
        /// <summary>
        /// Handles collision for when this wall is a wall.
        /// </summary>
        /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        void HandleCollideIntoWall(IMap map, Entity other, Vector2 displacement)
        {
            var displaced = false;

#if !TOPDOWN
            // Allow entities to walk up very small inclines. Makes no sense in top-down, so its used in sidescroller only.

            // Check if we have a displacement just on the X axis
            if (displacement.Y == 0)
            {
                // Check how far the "other" is from being on top of "this"
                var distFromThis = other.Max.Y - Position.Y;

                // If they are not that far away from being on top of "this", then instead of displacing them horizontally away
                // from us, pop them up on top of us, effectively "stepping" up
                if (distFromThis > 0 && distFromThis < _maxWallStepUpHeight)
                {
                    var horizontalOffset = (int)distFromThis + 1;
                    var otherRect        = other.ToRectangle();
                    otherRect.Y -= horizontalOffset;

                    // Make sure that if we move them up on top of us, that they will not be colliding with any walls. If they will
                    // be colliding with any walls, do NOT let them up here
                    if (!map.Spatial.Contains <WallEntityBase>(otherRect, x => !x.IsPlatform))
                    {
                        other.Move(new Vector2(0, -horizontalOffset));
                        displaced = true;
                    }
                }
            }
#endif

            // Move the other entity away from the wall using the MTD
            if (!displaced)
            {
                other.Move(displacement);
            }

            // Check for vertical collision
            if (displacement.Y != 0)
            {
                if (other.Velocity.Y >= 0 && displacement.Y < 0)
                {
                    // Collision from falling (land on feet)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                    other.StandingOn = this;
                }
                else if (other.Velocity.Y < 0 && displacement.Y > 0)
                {
                    // Collision from rising (hit head)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Handles collision for when this wall is a platform.
        /// </summary>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="wall">The wall/platform that the <paramref name="other"/> entity has collided into.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        static void HandleCollideIntoPlatform(Entity wall, Entity other, Vector2 displacement)
        {
            if (other.Velocity.Y <= 0 || displacement.Y >= 0 ||
                ((other.LastPosition.Y + other.Size.Y) > wall.Position.Y + _platformYPositionLeniency))
            {
                return;
            }

            // Move the other entity away from the wall
            displacement.X = 0;
            other.Move(displacement);

            // Collision from falling (land on feet)
            other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
            other.StandingOn = wall;
        }
Exemple #3
0
        /// <summary>
        /// Handles collision for when this wall is a wall.
        /// </summary>
        /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param>
        /// <param name="wall">The wall/platform that the <paramref name="other"/> entity has collided into.</param>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        /// <param name="moveVector">Vector describing how the entity has moved.</param>
        static void HandleCollideIntoWall(IMap map, Entity wall, Entity other, Vector2 displacement, Vector2 moveVector)
        {
            // NOTE: This seems to be working fine now, but it seems like we should stop calling this for walls once we move the "other" entity.

            bool displaced = false;

#if !TOPDOWN
            // Allow entities to walk up very small inclines. Makes no sense in top-down, so its used in sidescroller only.

            // Check if we have a displacement just on the X axis
            if (displacement.Y == 0)
            {
                // Check how far the "other" is from being on top of "this"
                var distFromThis = other.Max.Y - wall.Position.Y;

                // If they are not that far away from being on top of "this", then instead of displacing them horizontally away
                // from us, pop them up on top of us, effectively "stepping" up
                if (distFromThis > 0 && distFromThis < _maxWallStepUpHeight)
                {
                    var horizontalOffset = (int)distFromThis + 1;
                    var otherRect = other.ToRectangle();
                    otherRect.Y -= horizontalOffset;

                    // Make sure that if we move them up on top of us, that they will not be colliding with any walls. If they will
                    // be colliding with any walls, do NOT let them up here
                    if (!map.Spatial.Contains<WallEntityBase>(otherRect, x => !x.IsPlatform))
                    {
                        other.Move(new Vector2(0, -horizontalOffset));
                        displaced = true;
                    }
                }
            }
#endif

            if (ContainsWallAt(map, other.Position + displacement, other.Size))
            {
                moveVector = -moveVector;

                // If we can, offset by the move vector, preferring the smaller translation direction
                bool moved = false;

                Vector2 absMoveVector = moveVector.Abs();
                displacement = Vector2.Zero;

                // Check X, if x < y
                if (absMoveVector.X > 0 && (absMoveVector.Y <= float.Epsilon || absMoveVector.X < absMoveVector.Y))
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(moveVector.X, 0), other.Size))
                    {
                        moved = true;
                        displacement = new Vector2(moveVector.X, 0);
                    }
                }

                // Check Y
                if (!moved && absMoveVector.Y > 0)
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(0, moveVector.Y), other.Size))
                    {
                        moved = true;
                        displacement = new Vector2(0, moveVector.Y);
                    }
                }

                // Check X
                if (!moved && absMoveVector.X > 0)
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(moveVector.X, 0), other.Size))
                    {
                        moved = true;
                        displacement = new Vector2(moveVector.X, 0);
                    }
                }

                if (!moved)
                {
                    // Couldn't correct the movement? Send them back to where they came from!
                    displacement = moveVector;
                }
            }


            // Move the other entity away from the wall using the MTD
            if (!displaced)
            {
                other.Move(displacement);
            }

#if !TOPDOWN
            // Check for vertical collision
            if (displacement.Y != 0)
            {
                if (other.Velocity.Y >= 0 && displacement.Y < 0)
                {
                    // Collision from falling (land on feet)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                    other.StandingOn = wall;
                }
                else if (other.Velocity.Y < 0 && displacement.Y > 0)
                {
                    // Collision from rising (hit head)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                }
            }
#endif
        }
Exemple #4
0
        /// <summary>
        /// Handles collision for when this wall is a platform.
        /// </summary>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="wall">The wall/platform that the <paramref name="other"/> entity has collided into.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        static void HandleCollideIntoPlatform(Entity wall, Entity other, Vector2 displacement)
        {
            if (other.Velocity.Y <= 0 || displacement.Y >= 0 ||
                ((other.LastPosition.Y + other.Size.Y) > wall.Position.Y + _platformYPositionLeniency))
                return;

            // Move the other entity away from the wall
            displacement.X = 0;
            other.Move(displacement);

            // Collision from falling (land on feet)
            other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
            other.StandingOn = wall;
        }
        /// <summary>
        /// Handles collision for when this wall is a wall.
        /// </summary>
        /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        void HandleCollideIntoWall(IMap map, Entity other, Vector2 displacement)
        {
            var displaced = false;

#if !TOPDOWN
            // Allow entities to walk up very small inclines. Makes no sense in top-down, so its used in sidescroller only.

            // Check if we have a displacement just on the X axis
            if (displacement.Y == 0)
            {
                // Check how far the "other" is from being on top of "this"
                var distFromThis = other.Max.Y - Position.Y;

                // If they are not that far away from being on top of "this", then instead of displacing them horizontally away
                // from us, pop them up on top of us, effectively "stepping" up
                if (distFromThis > 0 && distFromThis < _maxWallStepUpHeight)
                {
                    var horizontalOffset = (int)distFromThis + 1;
                    var otherRect = other.ToRectangle();
                    otherRect.Y -= horizontalOffset;

                    // Make sure that if we move them up on top of us, that they will not be colliding with any walls. If they will
                    // be colliding with any walls, do NOT let them up here
                    if (!map.Spatial.Contains<WallEntityBase>(otherRect, x => !x.IsPlatform))
                    {
                        other.Move(new Vector2(0, -horizontalOffset));
                        displaced = true;
                    }
                }
            }
#endif

            // Move the other entity away from the wall using the MTD
            if (!displaced)
                other.Move(displacement);

            // Check for vertical collision
            if (displacement.Y != 0)
            {
                if (other.Velocity.Y >= 0 && displacement.Y < 0)
                {
                    // Collision from falling (land on feet)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                    other.StandingOn = this;
                }
                else if (other.Velocity.Y < 0 && displacement.Y > 0)
                {
                    // Collision from rising (hit head)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Handles collision for when this wall is a wall.
        /// </summary>
        /// <param name="map">The map that the <see cref="WallEntityBase"/> is on.</param>
        /// <param name="wall">The wall/platform that the <paramref name="other"/> entity has collided into.</param>
        /// <param name="other">The <see cref="Entity"/> that collided into this <see cref="WallEntityBase"/>.</param>
        /// <param name="displacement">The minimum transitional displacement to move the <paramref name="other"/>
        /// to make it no longer overlap this wall.</param>
        /// <param name="moveVector">Vector describing how the entity has moved.</param>
        static void HandleCollideIntoWall(IMap map, Entity wall, Entity other, Vector2 displacement, Vector2 moveVector)
        {
            // NOTE: This seems to be working fine now, but it seems like we should stop calling this for walls once we move the "other" entity.

            bool displaced = false;

#if !TOPDOWN
            // Allow entities to walk up very small inclines. Makes no sense in top-down, so its used in sidescroller only.

            // Check if we have a displacement just on the X axis
            if (displacement.Y == 0)
            {
                // Check how far the "other" is from being on top of "this"
                var distFromThis = other.Max.Y - wall.Position.Y;

                // If they are not that far away from being on top of "this", then instead of displacing them horizontally away
                // from us, pop them up on top of us, effectively "stepping" up
                if (distFromThis > 0 && distFromThis < _maxWallStepUpHeight)
                {
                    var horizontalOffset = (int)distFromThis + 1;
                    var otherRect        = other.ToRectangle();
                    otherRect.Y -= horizontalOffset;

                    // Make sure that if we move them up on top of us, that they will not be colliding with any walls. If they will
                    // be colliding with any walls, do NOT let them up here
                    if (!map.Spatial.Contains <WallEntityBase>(otherRect, x => !x.IsPlatform))
                    {
                        other.Move(new Vector2(0, -horizontalOffset));
                        displaced = true;
                    }
                }
            }
#endif

            if (ContainsWallAt(map, other.Position + displacement, other.Size))
            {
                moveVector = -moveVector;

                // If we can, offset by the move vector, preferring the smaller translation direction
                bool moved = false;

                Vector2 absMoveVector = moveVector.Abs();
                displacement = Vector2.Zero;

                // Check X, if x < y
                if (absMoveVector.X > 0 && (absMoveVector.Y <= float.Epsilon || absMoveVector.X < absMoveVector.Y))
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(moveVector.X, 0), other.Size))
                    {
                        moved        = true;
                        displacement = new Vector2(moveVector.X, 0);
                    }
                }

                // Check Y
                if (!moved && absMoveVector.Y > 0)
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(0, moveVector.Y), other.Size))
                    {
                        moved        = true;
                        displacement = new Vector2(0, moveVector.Y);
                    }
                }

                // Check X
                if (!moved && absMoveVector.X > 0)
                {
                    if (!ContainsWallAt(map, other.Position + new Vector2(moveVector.X, 0), other.Size))
                    {
                        moved        = true;
                        displacement = new Vector2(moveVector.X, 0);
                    }
                }

                if (!moved)
                {
                    // Couldn't correct the movement? Send them back to where they came from!
                    displacement = moveVector;
                }
            }


            // Move the other entity away from the wall using the MTD
            if (!displaced)
            {
                other.Move(displacement);
            }

#if !TOPDOWN
            // Check for vertical collision
            if (displacement.Y != 0)
            {
                if (other.Velocity.Y >= 0 && displacement.Y < 0)
                {
                    // Collision from falling (land on feet)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                    other.StandingOn = wall;
                }
                else if (other.Velocity.Y < 0 && displacement.Y > 0)
                {
                    // Collision from rising (hit head)
                    other.SetVelocity(new Vector2(other.Velocity.X, 0.0f));
                }
            }
#endif
        }