From 42edaaef0143d1051c54be21af88c0e56d0b0e53 Mon Sep 17 00:00:00 2001 From: Ben Frankel Date: Sun, 21 Jul 2024 13:36:48 -0700 Subject: [PATCH] Add health bar color ramp --- assets/config/health_bar.ron | 8 ++++++++ src/core/camera.rs | 1 - src/core/theme.rs | 1 - src/core/window.rs | 1 - src/game/actor.rs | 1 - src/game/actor/health.rs | 34 +++++++++++++++++++++++++++++++--- src/game/card.rs | 3 +-- src/game/step.rs | 1 - src/screen/loading.rs | 2 ++ src/screen/title.rs | 6 +++++- src/util/config.rs | 5 +++-- 11 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 assets/config/health_bar.ron diff --git a/assets/config/health_bar.ron b/assets/config/health_bar.ron new file mode 100644 index 0000000..c8be9fc --- /dev/null +++ b/assets/config/health_bar.ron @@ -0,0 +1,8 @@ +( + color_ramp: [ + Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 1.000)), + Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 1.000)), + Oklcha(Oklcha(lightness: 0.800, chroma: 0.300, hue: 090, alpha: 1.000)), + Oklcha(Oklcha(lightness: 0.700, chroma: 0.300, hue: 150, alpha: 1.000)), + ], +) diff --git a/src/core/camera.rs b/src/core/camera.rs index c00aa79..a6f72cf 100644 --- a/src/core/camera.rs +++ b/src/core/camera.rs @@ -20,7 +20,6 @@ struct CameraConfig { impl Config for CameraConfig { const PATH: &'static str = "config/camera.ron"; - const EXTENSION: &'static str = "camera.ron"; fn on_load(&mut self, world: &mut World) { diff --git a/src/core/theme.rs b/src/core/theme.rs index ec65f20..c996494 100644 --- a/src/core/theme.rs +++ b/src/core/theme.rs @@ -31,7 +31,6 @@ pub struct ThemeConfig { impl Config for ThemeConfig { const PATH: &'static str = "config/theme.ron"; - const EXTENSION: &'static str = "theme.ron"; fn on_load(&mut self, world: &mut World) { diff --git a/src/core/window.rs b/src/core/window.rs index bd4416f..b9cf0ce 100644 --- a/src/core/window.rs +++ b/src/core/window.rs @@ -35,7 +35,6 @@ pub struct WindowConfig { impl Config for WindowConfig { const PATH: &'static str = "config/window.ron"; - const EXTENSION: &'static str = "window.ron"; fn on_load(&mut self, world: &mut World) { diff --git a/src/game/actor.rs b/src/game/actor.rs index e1606d3..11496f0 100644 --- a/src/game/actor.rs +++ b/src/game/actor.rs @@ -38,7 +38,6 @@ pub struct ActorConfig { impl Config for ActorConfig { const PATH: &'static str = "config/actor.ron"; - const EXTENSION: &'static str = "actor.ron"; fn on_load(&mut self, world: &mut World) { diff --git a/src/game/actor/health.rs b/src/game/actor/health.rs index d03cb00..8eb65a3 100644 --- a/src/game/actor/health.rs +++ b/src/game/actor/health.rs @@ -1,11 +1,13 @@ use bevy::ecs::system::EntityCommand; use bevy::prelude::*; +use serde::Deserialize; +use serde::Serialize; use crate::core::UpdateSet; use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { - app.configure::<(Health, HealthBar)>(); + app.configure::<(Health, ConfigHandle, HealthBar)>(); } #[derive(Component, Reflect)] @@ -27,6 +29,29 @@ impl Health { } } +#[derive(Asset, Reflect, Serialize, Deserialize)] +pub struct HealthBarConfig { + pub color_ramp: Vec, +} + +impl Config for HealthBarConfig { + const PATH: &'static str = "config/health_bar.ron"; + const EXTENSION: &'static str = "health_bar.ron"; +} + +impl HealthBarConfig { + fn color(&self, t: f32) -> Color { + let t = t * (self.color_ramp.len() - 1) as f32; + let lo = t as usize; + let hi = lo + 1; + if hi >= self.color_ramp.len() { + self.color_ramp[self.color_ramp.len() - 1] + } else { + self.color_ramp[lo].mix(&self.color_ramp[hi], t.fract()) + } + } +} + /// Reads from the `Health` component on its parent entity. #[derive(Component, Reflect)] #[reflect(Component)] @@ -42,16 +67,19 @@ impl Configure for HealthBar { } fn update_health_bar( + config_handle: Res>, + config: Res>, health_query: Query<&Health>, mut health_bar_query: Query<(&HealthBar, &Parent, &mut Sprite)>, ) { + let config = r!(config.get(&config_handle.0)); + for (health_bar, parent, mut sprite) in &mut health_bar_query { let health = c!(health_query.get(parent.get())); let t = health.current / health.max; sprite.custom_size = Some(Vec2::new(t * health_bar.size.x, health_bar.size.y)); - // TODO: Color ramp. - sprite.color = Color::srgb(0.0, 1.0, 0.0); + sprite.color = config.color(t); } } diff --git a/src/game/card.rs b/src/game/card.rs index cbb60ef..ff6338b 100644 --- a/src/game/card.rs +++ b/src/game/card.rs @@ -42,8 +42,7 @@ fn enter_playing(world: &mut World) { action: id, }, )] - .into_iter() - .collect(), + .into(), )); } diff --git a/src/game/step.rs b/src/game/step.rs index ac1401f..ba4302b 100644 --- a/src/game/step.rs +++ b/src/game/step.rs @@ -18,7 +18,6 @@ struct StepConfig { impl Config for StepConfig { const PATH: &'static str = "config/step.ron"; - const EXTENSION: &'static str = "step.ron"; fn on_load(&mut self, world: &mut World) { diff --git a/src/screen/loading.rs b/src/screen/loading.rs index 7fce2a7..59a680b 100644 --- a/src/screen/loading.rs +++ b/src/screen/loading.rs @@ -4,6 +4,7 @@ use bevy_asset_loader::prelude::*; use iyes_progress::prelude::*; use pyri_state::prelude::*; +use crate::game::actor::health::HealthBarConfig; use crate::game::actor::ActorConfig; use crate::screen::fade_in; use crate::screen::fade_out; @@ -27,6 +28,7 @@ pub(super) fn plugin(app: &mut App) { Update, Screen::Loading.on_update(( ActorConfig::progress.track_progress(), + HealthBarConfig::progress.track_progress(), update_loading.after(TrackedProgressSet), )), ); diff --git a/src/screen/title.rs b/src/screen/title.rs index b34b2ac..442a53c 100644 --- a/src/screen/title.rs +++ b/src/screen/title.rs @@ -4,6 +4,7 @@ use bevy_mod_picking::prelude::*; use iyes_progress::prelude::*; use pyri_state::prelude::*; +use crate::game::actor::health::HealthBarConfig; use crate::game::actor::ActorConfig; use crate::screen::fade_in; use crate::screen::fade_out; @@ -22,7 +23,10 @@ pub(super) fn plugin(app: &mut App) { app.configure::(); app.add_systems( Update, - Screen::Title.on_update(ActorConfig::progress.track_progress()), + Screen::Title.on_update(( + ActorConfig::progress.track_progress(), + HealthBarConfig::progress.track_progress(), + )), ); } diff --git a/src/util/config.rs b/src/util/config.rs index 322c6e7..20b79df 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -12,10 +12,11 @@ use crate::util::prelude::*; pub trait Config: Asset + Serialize + for<'de> Deserialize<'de> { const PATH: &'static str; - const EXTENSION: &'static str; - fn on_load(&mut self, world: &mut World); + fn on_load(&mut self, world: &mut World) { + let _ = world; + } fn is_ready(&self, asset_server: &AssetServer) -> bool { let _ = asset_server;