diff --git a/Engines/FlatRedBallXNA/FlatRedBall/Entities/CameraControllingEntity.cs b/Engines/FlatRedBallXNA/FlatRedBall/Entities/CameraControllingEntity.cs
index 0c0fc2bcc..92f1ec3e5 100644
--- a/Engines/FlatRedBallXNA/FlatRedBall/Entities/CameraControllingEntity.cs
+++ b/Engines/FlatRedBallXNA/FlatRedBall/Entities/CameraControllingEntity.cs
@@ -16,8 +16,18 @@ public enum CameraBehaviorType
public enum TargetApproachStyle
{
+ ///
+ /// The camera moves to the target position immediately, effectively locking on to its position.
+ ///
Immediate,
+ ///
+ /// The camera moves to the target position smoothly, but not at a constant speed. The camera will move faster
+ /// if it is further away from the target, and slower if it is closer.
+ ///
Smooth,
+ ///
+ /// The camera moves to the target at a constant speed, regardless of the distance between the camera and the target.
+ ///
ConstantSpeed
}
@@ -36,6 +46,7 @@ public class CameraControllingEntity : PositionedObject
private float minZoomPercent;
private bool isAutoZoomEnabled;
private float furthestZoom;
+ private AxisAlignedRectangle MaximumViewRectangle = new AxisAlignedRectangle();
///
@@ -123,6 +134,9 @@ public bool LerpSmooth
}
}
+ ///
+ /// The type of approach to use when moving the camera to the target position.
+ ///
public TargetApproachStyle TargetApproachStyle { get; set; } = TargetApproachStyle.Smooth;
///
@@ -169,6 +183,7 @@ public float MaxViewableAreaMultiplier
///
public float MaxViewableAreaHeight => defaultOrthoHeight * MaxViewableAreaMultiplier;
+ public bool IsKeepingTargetsInView { get; set; } = false;
///
/// The amount of smoothing. The larger the number, faster the Camera moves. This value is ignored if TargetApproachStyle is Immediate.
@@ -292,12 +307,18 @@ public void Activity()
windowVisualization.Height = ScrollingWindowHeight;
}
+ if (IsKeepingTargetsInView && hasActivityBeenCalled)
+ {
+ KeepTargetsInView();
+ }
+
// Zoom should be happening first, and then targeting:
if (isAutoZoomEnabled)
{
ApplyZoom();
}
+
var target = GetTarget();
var effectiveTargetApproachStyleX =
@@ -347,6 +368,40 @@ public void Activity()
hasActivityBeenCalled = true;
}
+ private void KeepTargetsInView()
+ {
+ MaximumViewRectangle.Position = this.Position.AtZ(0);
+ MaximumViewRectangle.Width = MaxViewableAreaWidth;
+ MaximumViewRectangle.Height = MaxViewableAreaHeight;
+
+
+ for (int i = 0; i < Targets.Count; i++)
+ {
+ var target = Targets[i] as PositionedObject;
+
+ if(target != null)
+ {
+ if(target.Y > MaximumViewRectangle.Y + MaximumViewRectangle.Height / 2)
+ {
+ target.Y = MaximumViewRectangle.Y + MaximumViewRectangle.Height / 2;
+ }
+ else if(target.Y < MaximumViewRectangle.Y - MaximumViewRectangle.Height / 2)
+ {
+ target.Y = MaximumViewRectangle.Y - MaximumViewRectangle.Height / 2;
+ }
+
+ if(target.X > MaximumViewRectangle.X + MaximumViewRectangle.Width / 2)
+ {
+ target.X = MaximumViewRectangle.X + MaximumViewRectangle.Width / 2;
+ }
+ else if(target.X < MaximumViewRectangle.X - MaximumViewRectangle.Width / 2)
+ {
+ target.X = MaximumViewRectangle.X - MaximumViewRectangle.Width / 2;
+ }
+ }
+ }
+ }
+
private void ApplyZoom()
{
var separationVector = GetTargetSeparation();