public void DirectionNullTest() { var v = new Vector2(0, 0); Assert.AreEqual(null, DirectionHelper.FromVector(v)); }
public void DirectionEastTest() { var v = new Vector2(1, 0); Assert.AreEqual(Direction.East, DirectionHelper.FromVector(v)); }
public void DirectionNorthWestTest() { var v = new Vector2(-1, -1); Assert.AreEqual(Direction.NorthWest, DirectionHelper.FromVector(v)); }
/// <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 }