18 private const int InnerPadding = 2;
23 private bool _disposed;
24 private float _maximum;
27 private Point _offsetPx;
43 Point? offsetPx =
null,
44 string? nickname =
null)
50 Target = target ??
throw new ArgumentNullException(nameof(target));
53 throw new ArgumentOutOfRangeException(nameof(maximum),
"Maximum health must be greater than zero.");
57 _size = ValidateSize(size ??
new Size(64, 9));
58 _offsetPx = offsetPx ?? Point.Empty;
64 Color.FromArgb(220, 20, 24, 31),
67 new Rectangle(Point.Empty, _size),
68 $
"{nickname ?? Target.Nickname ?? "sprite
"}-health-track")
76 Color.FromArgb(245, 55, 210, 105),
79 GetFillBounds(Point.Empty),
80 $
"{nickname ?? Target.Nickname ?? "sprite
"}-health-fill")
87 keepCurrentOffset:
false,
88 explicitLocalOffsetPx: Vector2.Zero);
92 keepCurrentOffset:
false,
93 explicitLocalOffsetPx:
new Vector2(InnerPadding, InnerPadding));
95 Target.SpriteMoved += OnTargetMoved;
96 Target.Disposing += OnTargetDisposing;
116 throw new ArgumentOutOfRangeException(nameof(value),
"Maximum health must be greater than zero.");
119 _value = Math.Clamp(_value, 0f, _maximum);
132 float clamped = Math.Clamp(value, 0f,
Maximum);
134 if (_value.Equals(clamped))
155 Size validated = ValidateSize(value);
157 if (_size == validated)
161 _track.WorldBounds =
new Rectangle(_track.WorldBounds.Location, _size);
208 _fill.SetColor(color);
217 Rectangle targetBounds =
Target.DrawLocationWorld;
218 int x = targetBounds.Left + (targetBounds.Width -
Size.Width) / 2 +
OffsetPx.X;
219 int y = targetBounds.Top - Size.Height - 6 +
OffsetPx.Y;
231 Target.SpriteMoved -= OnTargetMoved;
232 Target.Disposing -= OnTargetDisposing;
240 _fill.Visible =
Value > 0f;
248 private void OnTargetDisposing(
Sprite sprite)
253 private void UpdateFillBounds()
255 Point location = _fill.WorldBounds.Location;
256 Rectangle fillBounds = GetFillBounds(location);
258 _fill.WorldBounds = fillBounds;
259 _fill.Visible =
Value > 0f && _track.Visible;
262 private Rectangle GetFillBounds(Point location)
264 int availableWidth = Math.Max(0,
Size.Width - InnerPadding * 2);
265 int availableHeight = Math.Max(1,
Size.Height - InnerPadding * 2);
266 int fillWidth = (int)MathF.Round(availableWidth *
Fraction);
268 return new Rectangle(location,
new Size(fillWidth, availableHeight));
271 private static Size ValidateSize(
Size value)
273 if (value.Width < InnerPadding * 2 + 1)
274 throw new ArgumentOutOfRangeException(nameof(value),
"Health-bar width is too small.");
276 if (value.Height < InnerPadding * 2 + 1)
277 throw new ArgumentOutOfRangeException(nameof(value),
"Health-bar height is too small.");
SceneLayer? SceneLayer
Gets the scene layer shared by all children in scene-layer mode.
virtual DirectComposite Add(IDirectCompositeChild child, bool keepCurrentOffset=true, Vector2? explicitLocalOffsetPx=null)
Adds a composite-compatible direct drawable as a child.
void SetPosition(Vector2 position)
Sets the composite anchor and repositions all children from their stored offsets.
Renders a configurable rectangle with support for fill, border, rounded corners, dash patterns,...
DirectRectangle SetFilled(bool isFilled)
Sets whether the rectangle interior is filled with the base color (or pattern).
DirectRectangle SetBorderColor(Color color)
Sets a distinct border (stroke) color, independent of the fill color.
StrokeAlign
Defines how the stroke (outline) is positioned relative to the rectangle's boundary.
DirectRectangle SetStrokeWidth(float width)
Sets the width (thickness) of the rectangle's stroke (outline) in pixels.
DirectRectangle SetCornerRadius(float radius)
Sets the radius for rounded corners in pixels.
DirectRectangle SetStrokeAlign(StrokeAlign align)
Sets how the rectangle's stroke is positioned relative to its bounds.
Provides data for sprite movement events.
Represents a movable visual element on a scene layer.
Represents a base class for hosting a render surface, providing functionality for managing rendering ...
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.