use bevy::prelude::*; #[derive(Resource)] pub struct Stamina { pub current: f32, pub max: f32, pub regen_rate: f32, // stamina per second pub regen_delay: f32, // seconds after last drain before regen pub time_since_drain: f32, } impl Stamina { pub fn new(max: f32) -> Self { Self { current: max, max, regen_rate: 80.0, regen_delay: 0.6, time_since_drain: 0.0, } } pub fn drain(&mut self, amount: f32) { self.current = (self.current - amount).max(0.0); self.time_since_drain = 0.0; } pub fn regen(&mut self, dt: f32) { if self.time_since_drain >= self.regen_delay { self.current = (self.current + self.regen_rate * dt) .min(self.max); } else { self.time_since_drain += dt; } } pub fn ratio(&self) -> f32 { self.current / self.max } } use bevy_egui::{EguiContexts, EguiPlugin}; pub struct StaminaPlugin; impl Plugin for StaminaPlugin { fn build(&self, app: &mut App) { app .insert_resource(Stamina::new(360.0)) .add_systems(Update, ( stamina_input_system, stamina_regen_system, stamina_ui_system, )); } } fn stamina_input_system( mouse: Res>, mut stamina: ResMut, ) { if mouse.just_pressed(MouseButton::Left) { if stamina.current >= 40.0 { stamina.drain(40.0); // Trigger slash animation here } } } use bevy_egui::egui; use std::f32::consts::TAU; fn stamina_ui_system( mut contexts: EguiContexts, stamina: Res, ) { egui::Area::new("stamina_ui") .fixed_pos(egui::pos2(40.0, 40.0)) .show(contexts.ctx_mut(), |ui| { let size = egui::vec2(90.0, 90.0); let (rect, _) = ui.allocate_exact_size(size, egui::Sense::hover()); let painter = ui.painter(); let center = rect.center(); let radius = rect.width() * 0.45; let start_angle = -TAU / 4.0; let end_angle = start_angle + TAU * stamina.ratio(); // Background ring painter.circle_stroke( center, radius, egui::Stroke::new(6.0, egui::Color32::DARK_GRAY), ); // Stamina arc painter.arc( center, radius, start_angle, end_angle, egui::Stroke::new(6.0, egui::Color32::from_rgb(70, 220, 120)), ); }); } fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(EguiPlugin) .add_plugins(StaminaPlugin) .run(); }