示例#1
0
        public void DirectionNullTest()
        {
            var v = new Vector2(0, 0);

            Assert.AreEqual(null, DirectionHelper.FromVector(v));
        }
示例#2
0
        public void DirectionEastTest()
        {
            var v = new Vector2(1, 0);

            Assert.AreEqual(Direction.East, DirectionHelper.FromVector(v));
        }
示例#3
0
        public void DirectionNorthWestTest()
        {
            var v = new Vector2(-1, -1);

            Assert.AreEqual(Direction.NorthWest, DirectionHelper.FromVector(v));
        }
示例#4
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>
        /// <param name="blockedDirection">Direction to not allow movement through this <paramref name="wall"/>.</param>
        static void HandleCollideIntoWall(IMap map, Entity wall, Entity other, Vector2 displacement, Vector2 moveVector, Direction blockedDirection)
        {
            // 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;
                }
            }

            // Check if there is an actual blocked direction
            if (blockedDirection != Direction.None)
            {
                // Get the other's direction from it's vector
                var otherDirection = DirectionHelper.FromVector(moveVector);
                // If they aren't opposite directions, allow movement through the wall
                if (!IfOppositeDirections(blockedDirection, otherDirection))
                {
                    displaced = true;
                }
            }

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