outfly/src/menu.rs

146 lines
5.4 KiB
Rust
Raw Normal View History

2024-05-12 20:17:17 +00:00
// ▄████████▄ + ███ + ▄█████████ ███ +
// ███▀ ▀███ + + ███ ███▀ + ███ + +
// ███ + ███ ███ ███ █████████ ███ ███ ███ ███
// ███ +███ ███ ███ ███ ███▐██████ ███ ███ ███
// ███ + ███ ███+ ███ +███ ███ + ███ ███ + ███
// ███▄ ▄███ ███▄ ███ ███ + ███ + ███ ███▄ ███
// ▀████████▀ + ▀███████ ███▄ ███▄ ▀████ ▀███████
// + + + ███
// + ▀████████████████████████████████████████████████████▀
//
// This plugin manages game menus and the player death screen
use crate::prelude::*;
use bevy::prelude::*;
pub struct MenuPlugin;
impl Plugin for MenuPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup.after(hud::setup));
app.add_systems(PreUpdate, show_deathscreen.run_if(on_event::<DeathScreenEvent>()));
app.add_systems(Update, handle_deathscreen_input);
app.add_event::<DeathScreenEvent>();
}
}
#[derive(Component)] pub struct DeathScreenElement;
#[derive(Component)] pub struct BlackScreen;
#[derive(Component)] pub struct DeathText;
#[derive(Event, PartialEq)] pub enum DeathScreenEvent { Show, Hide }
pub fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
settings: Res<Settings>,
) {
commands.spawn((
BlackScreen,
DeathScreenElement,
NodeBundle {
style: Style {
width: Val::Vw(100.0),
height: Val::Vh(100.0),
position_type: PositionType::Absolute,
top: Val::Px(0.0),
left: Val::Px(0.0),
..default()
},
background_color: Color::BLACK.into(),
visibility: Visibility::Hidden,
..default()
},
));
let font_handle = asset_server.load(FONT);
let style_death = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_deathtext,
color: settings.hud_color_subtitles,
..default()
};
let style_death_subtext = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_deathsubtext,
color: settings.hud_color_subtitles,
..default()
};
let style_death_subsubtext = TextStyle {
font: font_handle.clone(),
font_size: settings.font_size_deathsubtext * 0.8,
color: settings.hud_color_subtitles,
..default()
};
commands.spawn((
DeathScreenElement,
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::SpaceAround,
..default()
},
visibility: Visibility::Hidden,
..default()
},
)).with_children(|builder| {
builder.spawn((
DeathText,
TextBundle {
text: Text {
sections: vec![
TextSection::new("You are dead.\n", style_death),
TextSection::new("Cause: ", style_death_subtext.clone()),
TextSection::new("Unknown", style_death_subtext),
TextSection::new("\n\n\nPress E to begin anew.", style_death_subsubtext),
],
justify: JustifyText::Center,
..default()
},
..default()
},
));
});
}
pub fn show_deathscreen(
mut er_deathscreen: EventReader<DeathScreenEvent>,
mut q_vis: Query<&mut Visibility, With<DeathScreenElement>>,
mut q_text: Query<&mut Text, With<DeathText>>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_effect: EventWriter<visual::SpawnEffectEvent>,
mut ew_respawn: EventWriter<world::RespawnEvent>,
2024-05-12 20:17:17 +00:00
mut settings: ResMut<Settings>,
) {
for event in er_deathscreen.read() {
let show = *event == DeathScreenEvent::Show;
for mut vis in &mut q_vis {
*vis = bool2vis(show);
}
settings.deathscreen_active = show;
if show {
if let Ok(mut text) = q_text.get_single_mut() {
text.sections[2].value = settings.death_cause.clone();
}
} else {
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::WakeUp));
ew_effect.send(visual::SpawnEffectEvent { class: visual::Effects::FadeIn(Color::BLACK), duration: 0.3 });
ew_respawn.send(world::RespawnEvent);
2024-05-12 20:17:17 +00:00
}
}
}
pub fn handle_deathscreen_input(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut ew_deathscreen: EventWriter<DeathScreenEvent>,
settings: ResMut<Settings>,
) {
if !settings.deathscreen_active {
return;
}
if keyboard_input.pressed(settings.key_interact) {
ew_deathscreen.send(DeathScreenEvent::Hide);
}
}