avoid-rs/src/hud.rs

181 lines
4.5 KiB
Rust
Raw Normal View History

2025-01-01 18:52:19 +02:00
use std::path::Path;
use bevy::{
asset::{io::AssetSourceId, AssetPath},
prelude::*,
};
use crate::{player::Player, score::Score, GameStartEvent, GameState, START_POSITION};
pub struct HUDPlugin;
impl Plugin for HUDPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, setup);
app.add_systems(Update, start_button_logic);
}
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// let asset_path: AssetPath = "embedded://avoid_rs/assets/Xolonium-Regular.ttf".into();
let asset_path: AssetPath = "Xolonium-Regular.ttf".into();
let font: Handle<_> = asset_server.load(asset_path);
// let path = Path::new("avoid-rs").join("assets/Xolonium-Regular.ttf");
// let source = AssetSourceId::from("embedded");
// let asset_path = AssetPath::from_path(&path).with_source(source);
// let font: Handle<_> = asset_server.load(asset_path);
// score UI, top middle
commands
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..Default::default()
},
..Default::default()
})
.with_children(|parent| {
parent.spawn((
TextBundle::from_section(
"0",
TextStyle {
font: font.clone(),
font_size: 64.0,
..Default::default()
},
)
.with_text_justify(JustifyText::Center)
.with_style(Style {
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
}),
ScoreText,
));
});
commands
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..Default::default()
},
..Default::default()
})
.with_children(|parent| {
// game info, middle of the screen
parent.spawn((
TextBundle::from_section(
"Dodge the creeps!",
TextStyle {
font: font.clone(),
font_size: 64.0,
..Default::default()
},
)
.with_text_justify(JustifyText::Center)
.with_style(Style {
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
}),
IntroMessageText,
StartMenuUI,
));
});
commands
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(90.0),
align_items: AlignItems::End,
justify_content: JustifyContent::Center,
..Default::default()
},
..Default::default()
})
.with_children(|parent| {
parent
.spawn((
ButtonBundle {
style: Style {
width: Val::Px(200.0),
height: Val::Px(100.0),
border: UiRect::all(Val::Px(5.0)),
// horizontally center child text
justify_content: JustifyContent::Center,
// vertically center child text
align_items: AlignItems::Center,
..default()
},
border_color: BorderColor(Color::BLACK),
border_radius: BorderRadius::all(Val::Px(10.0)),
background_color: Color::srgb(0.15, 0.15, 0.15).into(),
..default()
},
StartButton,
StartMenuUI,
))
.with_children(|parent| {
parent.spawn(TextBundle::from_section(
"Start",
TextStyle {
font: font.clone(),
font_size: 64.0,
color: Color::srgb(0.9, 0.9, 0.9),
},
));
});
});
}
#[derive(Component)]
pub struct ScoreText;
#[derive(Component)]
pub struct IntroMessageText;
#[derive(Component)]
pub struct StartButton;
#[derive(Component)]
pub struct StartMenuUI;
fn start_button_logic(
mut state: ResMut<NextState<GameState>>,
mut score: ResMut<Score>,
mut button: Query<(&Interaction, &mut BorderColor), With<StartButton>>,
mut player_query: Query<(&mut Transform, &mut Visibility), With<Player>>,
mut ui_elems_query: Query<&mut Visibility, (With<StartMenuUI>, Without<Player>)>,
mut score_text_query: Query<&mut Text, With<ScoreText>>,
) {
let (interaction, mut border_color) = button.single_mut();
match *interaction {
Interaction::Pressed => {
let mut score_text = score_text_query.single_mut();
score.0 = 0;
score_text.sections[0].value = format!("{}", score.0);
state.set(GameState::Playing);
let (mut player_transform, mut player_visibility) = player_query.single_mut();
for mut elem in &mut ui_elems_query {
*elem = Visibility::Hidden;
}
*player_visibility = Visibility::Visible;
player_transform.translation = START_POSITION;
}
Interaction::Hovered => border_color.0 = Color::WHITE,
Interaction::None => border_color.0 = Color::BLACK,
}
}