Skip to content

Instantly share code, notes, and snippets.

@Kielan
Created December 17, 2025 00:09
Show Gist options
  • Select an option

  • Save Kielan/b3e7bfd5d7e8699b7dafa2af66a88a84 to your computer and use it in GitHub Desktop.

Select an option

Save Kielan/b3e7bfd5d7e8699b7dafa2af66a88a84 to your computer and use it in GitHub Desktop.
Rust bevy egui stamina.
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