Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
HealthBarWidget.cs
1using System.Drawing;
2using System.Numerics;
6
8
16public sealed class HealthBarWidget : WidgetBase
17{
18 private const int InnerPadding = 2;
19
20 private readonly DirectRectangle _track;
21 private readonly DirectRectangle _fill;
22
23 private bool _disposed;
24 private float _maximum;
25 private float _value;
26 private Size _size;
27 private Point _offsetPx;
28
39 RenderSurfaceHostBase renderSurfaceHost,
40 Sprite target,
41 float maximum,
42 Size? size = null,
43 Point? offsetPx = null,
44 string? nickname = null)
45 : base(
46 renderSurfaceHost,
48 nickname: nickname)
49 {
50 Target = target ?? throw new ArgumentNullException(nameof(target));
51
52 if (maximum <= 0f)
53 throw new ArgumentOutOfRangeException(nameof(maximum), "Maximum health must be greater than zero.");
54
55 _maximum = maximum;
56 _value = maximum;
57 _size = ValidateSize(size ?? new Size(64, 9));
58 _offsetPx = offsetPx ?? Point.Empty;
59
60 IsInputEnabled = false;
62
63 _track = new DirectRectangle(
64 Color.FromArgb(220, 20, 24, 31),
65 renderSurfaceHost,
66 Target.SceneLayer,
67 new Rectangle(Point.Empty, _size),
68 $"{nickname ?? Target.Nickname ?? "sprite"}-health-track")
69 .SetFilled(true)
70 .SetBorderColor(Color.FromArgb(235, 235, 241, 247))
73 .SetCornerRadius(2f);
74
75 _fill = new DirectRectangle(
76 Color.FromArgb(245, 55, 210, 105),
77 renderSurfaceHost,
78 Target.SceneLayer,
79 GetFillBounds(Point.Empty),
80 $"{nickname ?? Target.Nickname ?? "sprite"}-health-fill")
81 .SetFilled(true)
83 .SetCornerRadius(1f);
84
85 Add(
86 _track,
87 keepCurrentOffset: false,
88 explicitLocalOffsetPx: Vector2.Zero);
89
90 Add(
91 _fill,
92 keepCurrentOffset: false,
93 explicitLocalOffsetPx: new Vector2(InnerPadding, InnerPadding));
94
95 Target.SpriteMoved += OnTargetMoved;
96 Target.Disposing += OnTargetDisposing;
97
99 UpdateFillBounds();
100 }
101
105 public Sprite Target { get; }
106
110 public float Maximum
111 {
112 get => _maximum;
113 set
114 {
115 if (value <= 0f)
116 throw new ArgumentOutOfRangeException(nameof(value), "Maximum health must be greater than zero.");
117
118 _maximum = value;
119 _value = Math.Clamp(_value, 0f, _maximum);
120 UpdateFillBounds();
121 }
122 }
123
127 public float Value
128 {
129 get => _value;
130 set
131 {
132 float clamped = Math.Clamp(value, 0f, Maximum);
133
134 if (_value.Equals(clamped))
135 return;
136
137 _value = clamped;
138 UpdateFillBounds();
139 }
140 }
141
145 public float Fraction => Value / Maximum;
146
150 public Size Size
151 {
152 get => _size;
153 set
154 {
155 Size validated = ValidateSize(value);
156
157 if (_size == validated)
158 return;
159
160 _size = validated;
161 _track.WorldBounds = new Rectangle(_track.WorldBounds.Location, _size);
163 UpdateFillBounds();
164 }
165 }
166
170 public Point OffsetPx
171 {
172 get => _offsetPx;
173 set
174 {
175 _offsetPx = value;
177 }
178 }
179
183 public Rectangle TrackBoundsWorld => _track.WorldBounds;
184
188 public Rectangle FillBoundsWorld => _fill.WorldBounds;
189
195 public HealthBarWidget SetValue(float value)
196 {
197 Value = value;
198 return this;
199 }
200
206 public HealthBarWidget SetFillColor(Color color)
207 {
208 _fill.SetColor(color);
209 return this;
210 }
211
215 public void RefreshPosition()
216 {
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;
220
221 SetPosition(x, y);
222 }
223
225 public override void Dispose()
226 {
227 if (_disposed)
228 return;
229
230 _disposed = true;
231 Target.SpriteMoved -= OnTargetMoved;
232 Target.Disposing -= OnTargetDisposing;
233 base.Dispose();
234 }
235
237 protected override void ProcessShown()
238 {
239 base.ProcessShown();
240 _fill.Visible = Value > 0f;
241 }
242
243 private void OnTargetMoved(SpriteMovedEventArgs args)
244 {
246 }
247
248 private void OnTargetDisposing(Sprite sprite)
249 {
250 Dispose();
251 }
252
253 private void UpdateFillBounds()
254 {
255 Point location = _fill.WorldBounds.Location;
256 Rectangle fillBounds = GetFillBounds(location);
257
258 _fill.WorldBounds = fillBounds;
259 _fill.Visible = Value > 0f && _track.Visible;
260 }
261
262 private Rectangle GetFillBounds(Point location)
263 {
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);
267
268 return new Rectangle(location, new Size(fillWidth, availableHeight));
269 }
270
271 private static Size ValidateSize(Size value)
272 {
273 if (value.Width < InnerPadding * 2 + 1)
274 throw new ArgumentOutOfRangeException(nameof(value), "Health-bar width is too small.");
275
276 if (value.Height < InnerPadding * 2 + 1)
277 throw new ArgumentOutOfRangeException(nameof(value), "Health-bar height is too small.");
278
279 return value;
280 }
281}
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.
Definition Sprite.cs:20
Represents a base class for hosting a render surface, providing functionality for managing rendering ...
float Maximum
Gets or sets the maximum health value.
float Fraction
Gets the filled fraction in the range zero through one.
Point OffsetPx
Gets or sets an additional world-pixel offset from the centered position above the target.
Size Size
Gets or sets the outer bar size in world pixels.
Rectangle FillBoundsWorld
Gets the current world bounds of the filled portion.
override void ProcessShown()
Performs processing when the widget is shown before notification callbacks are invoked.
HealthBarWidget(RenderSurfaceHostBase renderSurfaceHost, Sprite target, float maximum, Size? size=null, Point? offsetPx=null, string? nickname=null)
Initializes a health bar that follows target .
Sprite Target
Gets the sprite followed by this health bar.
HealthBarWidget SetFillColor(Color color)
Sets the fill color and returns this widget.
Rectangle TrackBoundsWorld
Gets the current world bounds of the health-bar track.
override void Dispose()
Disposes the composite and every child it owns.
HealthBarWidget SetValue(float value)
Sets the current health and returns this widget for fluent setup.
float Value
Gets or sets the current health value. Values are clamped to zero through Maximum.
void RefreshPosition()
Repositions the bar from the target's current render bounds.
bool IsPointerInputEnabled
Gets or sets a value indicating whether the widget can receive pointer input.
WidgetBase(RenderSurfaceHostBase renderSurfaceHost, DirectDrawingMode mode, PointF anchor=default, string? nickname=null)
Initializes a new instance of the WidgetBase class.
Definition WidgetBase.cs:95
bool IsInputEnabled
Gets or sets a value indicating whether the widget can participate in input routing.
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.