Commit edbd3622 authored by Simon Goller's avatar Simon Goller Committed by neosam
Browse files

Add stamina

Stamina is a component and can be assigned to any entities.  The
stamina_regeneration_system will automatically refill the stamina
until it's completely full.

The player has an own system which will update the stamina bar
based on the player's stamina and will hide it, when the stamina
is full.
parent 0fa58a8e
......@@ -9,6 +9,7 @@ mod player;
mod position;
mod sprite;
mod thesun;
mod stamina;
pub use edge::draw_edges_system;
pub use edge::Edge;
......@@ -23,5 +24,6 @@ pub use orbitbody::{Gravity, OrbitBody};
pub use player::Player;
pub use position::{Position, Rotation};
pub use sprite::Sprite;
pub use stamina::Stamina;
pub use thesun::draw_thesun_system;
pub use thesun::TheSun;
use crate::data_types;
pub struct Stamina {
pub progress: data_types::Progress,
/// Regeneration of the stamina per second
pub regeneration: f32,
}
impl Stamina {
pub fn new(max_value: f32, regeneration: f32) -> Self {
Stamina {
progress: data_types::Progress::with_full_value(max_value),
regeneration,
}
}
}
......@@ -12,4 +12,8 @@ impl Progress {
pub fn relative_value(&self) -> f32 {
self.value / self.max
}
pub fn modify(&mut self, delta: f32) {
self.value = (self.value + delta).min(self.max).max(0.0);
}
}
......@@ -22,5 +22,6 @@ pub fn create_player(
components::Movable::new(),
colliders::Collider::new_player(50.0),
components::Sprite::new(sprites::Sprite::Player),
components::Stamina::new(30.0, 5.0),
))
}
......@@ -26,6 +26,8 @@ impl InGameState {
assigned_shift: angel_shifts::AngelShift,
) -> InGameState {
let sanity_bar = utils::get_element_by_id("sanity-amount").unwrap();
let stamina_bar = utils::get_element_by_id("stamina-bar").unwrap();
let stamina_amount = utils::get_element_by_id("stamina-amount").unwrap();
let foreground = rendering.register_image(level.foreground_image.clone());
let background = rendering.register_image(level.background_image.clone());
......@@ -61,10 +63,12 @@ impl InGameState {
.flush()
.add_thread_local(systems::reduce_sanity_obstacle_system())
.add_thread_local(systems::player_sanity_check_system())
.add_thread_local(systems::stamina_regeneration_system())
.add_thread_local(systems::update_game_manager_system())
.add_thread_local(systems::move_camera_to_player_system())
.add_thread_local(systems::camera_system())
.add_thread_local(systems::update_sanity_bar_system(sanity_bar))
.add_thread_local(systems::update_stamina_bar_system(stamina_bar, stamina_amount))
.add_thread_local(systems::draw_level_layer_system(background))
.add_thread_local(systems::draw_sprites_system())
.add_thread_local(systems::draw_level_layer_system(foreground))
......
......@@ -5,6 +5,7 @@ mod level;
mod moving;
mod player;
mod sprite;
mod stamina;
mod tmp_stationary_obstacles;
pub use camera::camera_system;
......@@ -14,8 +15,10 @@ pub use level::draw_level_layer_system;
pub use moving::{move_camera_to_player_system, move_movable_system};
pub use player::{
player_sanity_check_system, sanity_goes_up_and_down_system, update_sanity_bar_system,
update_stamina_bar_system
};
pub use sprite::draw_sprites_system;
pub use stamina::stamina_regeneration_system;
pub use tmp_stationary_obstacles::{
draw_tmp_stationary_obstacles_barrier_system, reduce_sanity_obstacle_system,
};
......@@ -30,6 +30,31 @@ pub fn update_sanity_bar(
.unwrap();
}
#[legion::system]
#[read_component(components::Player)]
#[read_component(components::Stamina)]
pub fn update_stamina_bar(
world: &legion::world::SubWorld,
#[resource] player: &resources::Player,
#[state] stamina_bar: &mut web_sys::SvgElement,
#[state] stamina_amount: &mut web_sys::Element,
) {
let mut players = <(&components::Player, &components::Stamina)>::query();
let (_player, stamina) = players.get(world, player.0).unwrap();
stamina_amount
.set_attribute(
"width",
&(stamina.progress.relative_value() * 1000.0).to_string(),
)
.unwrap();
stamina_bar
.style().set_property(
"display", if stamina.progress.relative_value() == 1.0 { "none" } else { "block" }
)
.unwrap();
}
#[legion::system]
#[write_component(components::Player)]
pub fn player_sanity_check(
......
use crate::components;
use crate::resources;
#[legion::system(for_each)]
#[write_component(components::Stamina)]
pub fn stamina_regeneration(
#[resource] clock: &resources::Clock,
stamina: &mut components::Stamina,
) {
stamina.progress.modify(stamina.progress.value * clock.frame_delta());
}
\ No newline at end of file
......@@ -15,6 +15,11 @@
<rect x="460" y="100" width="600" height="40" class="sanity-amount" id="sanity-amount" />
<rect x="460" y="100" width="1000" height="40" class="sanity-outline" />
<g id="stamina-bar" class="stamina-bar">
<rect x="460" y="150" width="600" height="20" class="stamina-amount" id="stamina-amount" />
<rect x="460" y="150" width="1000" height="20" class="stamina-outline" />
</g>
<defs>
<linearGradient id="objective-bg-gradient" x1="0" x2="0" y1="0" y2="1">
<stop class="objective-background stop1" offset="0%" />
......
......@@ -191,6 +191,18 @@ div.game {
stroke: #ffffff;
stroke-width: 4px;
}
g.stamina-bar {
rect.stamina-amount {
fill: $typography-2;
}
rect.stamina-outline {
fill: transparent;
stroke: #ffffff;
stroke-width: 2px;
}
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment