Presentation helper for a stamina bar. Samples each player's stamina from MatchSimulation, detects drops to flash a fill indicator, and smooths the fill and opacity values for drawing. Never writes back to player state.
using System;
namespace Socer;
// Presentation only: follows real expenditure, never writes player stamina.
public sealed class StaminaReadout
{
readonly float[] previous=new float[22],remaining=new float[22];
public float[] Fill=new float[22],Opacity=new float[22];
MatchSimulation match;
float sampledSeconds=-1;
public void Update(MatchSimulation m,float dt,bool paused)
{
dt=Math.Clamp(dt,0,.1f);
if(match!=m)
{
match=m;sampledSeconds=m.Seconds;Array.Clear(remaining);Array.Clear(Opacity);
foreach(var p in m.Players)previous[p.Id]=Fill[p.Id]=p.Stamina;
return;
}
bool fresh=m.Seconds!=sampledSeconds;
foreach(var p in m.Players)
{
if(fresh && previous[p.Id]-p.Stamina>.000001f)remaining[p.Id]=.75f;
if(fresh)previous[p.Id]=p.Stamina;
if(!paused)remaining[p.Id]=Math.Max(0,remaining[p.Id]-dt);
Fill[p.Id]+=(p.Stamina-Fill[p.Id])*(1-MathF.Exp(-dt*12));
Opacity[p.Id]=p.SentOff?0:Math.Clamp(remaining[p.Id]/.3f,0,1);
}
sampledSeconds=m.Seconds;
}
}