Created
December 17, 2025 00:09
-
-
Save Kielan/b3e7bfd5d7e8699b7dafa2af66a88a84 to your computer and use it in GitHub Desktop.
Rust bevy egui stamina.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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<Input<MouseButton>>, | |
| mut stamina: ResMut<Stamina>, | |
| ) { | |
| 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<Stamina>, | |
| ) { | |
| 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(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment