protected override MoveResult UpdatePosition(GameTime gameTime, Vector2 interpolation) { MoveResult result = Movement.Move(this, interpolation); var blocked = result.HasFlag(MoveResult.Blocked); if (blocked) // collided. { Direction = Direction.None; Speed = Vector2.Zero; } else { Position = BoundingBox.GetPosition(this); if (!result.HasFlag(MoveResult.X) || result.HasFlag(MoveResult.FlattenXSpeed)) { Speed.X = 0; } if (!result.HasFlag(MoveResult.Y) || result.HasFlag(MoveResult.FlattenYSpeed)) { Speed.Y = interpolationCalculator.CalculateGravitySpeed(gameTime).Y; } } return(result); }
private Vector2 Think(GameTime gameTime, int thoughts = 3) { FloatRectangle aabb = BoundingBox.Bounds; Vector2 interpolation = Movement.InterpolationCalculator.CalculateInterpolation(gameTime); if (interpolation == Vector2.Zero) { return(interpolation); } Vector2 movement = AddMargin(interpolation) + MagicNumbers.GloopVertigoMargin; MoveResult predicted = Movement.CollisionDetection.CanMoveInterpolated(aabb, movement, DetectionType.Collision); if (!predicted.HasFlag(MoveResult.BlockedOnNegativeX) && !predicted.HasFlag(MoveResult.BlockedOnPositiveX) && predicted.HasFlag(MoveResult.BlockedOnPositiveY)) { return(interpolation); } else if (thoughts > 0) { ToggleDirection(); return(Think(gameTime, --thoughts)); } else { return(Vector2.Zero); } }
protected override MoveResult UpdatePosition(GameTime gameTime, Vector2 interpolation) { var wasAirborne = State == HitBoxState.Airborne; MoveResult result = base.UpdatePosition(gameTime, interpolation); if (!result.HasFlag(MoveResult.Y) || result.HasFlag(MoveResult.FlattenYSpeed)) // sanity. { lastJumpStarted = null; } if (result == MoveResult.Died) { Die(); } else if (result == MoveResult.LevelCompleted) { CompleteLevel(); } else if (wasAirborne) { if (jumpStartPosition.HasValue && Position.Y > jumpStartPosition.Value.Y) { jumpStartPosition = null; // avoid repetition. FallEffects(); } if (State == HitBoxState.Surfaced) { Direction = Direction.None; IdleEffects(); } } return(result); }
private MoveResult Reposition(IHitBox hitBox, MoveResult result, Vector2 interpolation) { AxisAlignedBoundingBox aabb = hitBox.BoundingBox; var moveX = result.HasFlag(MoveResult.X) && !result.HasFlag(MoveResult.BlockedOnNegativeX) && !result.HasFlag(MoveResult.BlockedOnPositiveX); if (moveX) { aabb.Position.X += interpolation.X; } bool surfaced = CanSetSurfaced(hitBox); var moveY = result.HasFlag(MoveResult.Y) && !result.HasFlag(MoveResult.BlockedOnNegativeY) && !result.HasFlag(MoveResult.BlockedOnPositiveY); if ((moveY || !surfaced) && !result.HasFlag(MoveResult.Died)) { hitBox.State = HitBoxState.Airborne; } else { hitBox.State = HitBoxState.Surfaced; } if (moveY && !result.HasFlag(MoveResult.Died)) { aabb.Position.Y += interpolation.Y; } var reverse = CollisionDetection.CanMove(aabb.Bounds, -interpolation, DetectionType.Retrace); if (moveX) // fix issue when moving on X axis to the left. { if (reverse.HasFlag(MoveResult.BlockedOnNegativeX) && interpolation.X > 0) { aabb.Position.X -= interpolation.X; result &= ~MoveResult.X; } else if (reverse.HasFlag(MoveResult.BlockedOnPositiveX) && interpolation.X < 0) { aabb.Position.X -= interpolation.X; result &= ~MoveResult.X; } } if (moveY) // fix issue when hitting an impassable on Y axis when jumping. { if (reverse.HasFlag(MoveResult.BlockedOnNegativeY) && interpolation.Y > 0) { aabb.Position.Y -= interpolation.Y; result &= ~MoveResult.Y; } else if (reverse.HasFlag(MoveResult.BlockedOnPositiveY) && interpolation.Y < 0) { aabb.Position.Y -= interpolation.Y; result &= ~MoveResult.Y; } } return(result); }
private MoveResult Reposition(IHitBox hitBox, MoveResult result, Vector2 interpolation) { AxisAlignedBoundingBox aabb = hitBox.BoundingBox; var moveX = result.HasFlag(MoveResult.X) && !result.HasFlag(MoveResult.BlockedOnNegativeX) && !result.HasFlag(MoveResult.BlockedOnPositiveX); if (moveX) { aabb.Position.X += interpolation.X; } bool surfaced = CanSetSurfaced(hitBox); var moveY = result.HasFlag(MoveResult.Y) && !result.HasFlag(MoveResult.BlockedOnNegativeY) && !result.HasFlag(MoveResult.BlockedOnPositiveY); if ((moveY || !surfaced) && !result.HasFlag(MoveResult.Died)) { hitBox.State = HitBoxState.Airborne; } else { hitBox.State = HitBoxState.Surfaced; } if (moveY && !result.HasFlag(MoveResult.Died)) { aabb.Position.Y += interpolation.Y; } var reverse = CollisionDetection.CanMove(aabb.Bounds, -interpolation, DetectionType.Retrace); if (moveX) // fix issue when moving on X axis to the left. { if (reverse.HasFlag(MoveResult.BlockedOnNegativeX) && interpolation.X > 0) { aabb.Position.X -= interpolation.X; result &= ~MoveResult.X; } else if (reverse.HasFlag(MoveResult.BlockedOnPositiveX) && interpolation.X < 0) { aabb.Position.X -= interpolation.X; result &= ~MoveResult.X; } } if (moveY) // fix issue when hitting an impassable on Y axis when jumping. { if (reverse.HasFlag(MoveResult.BlockedOnNegativeY) && interpolation.Y > 0) { aabb.Position.Y -= interpolation.Y; result &= ~MoveResult.Y; } else if (reverse.HasFlag(MoveResult.BlockedOnPositiveY) && interpolation.Y < 0) { aabb.Position.Y -= interpolation.Y; result &= ~MoveResult.Y; } } return result; }