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.

Revisions

  1. Kielan created this gist Dec 17, 2025.
    115 changes: 115 additions & 0 deletions main.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    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();
    }