use bevy::{asset::AssetPath, prelude::*}; use crate::{player::Player, score::Score, 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) { // 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((Node { width: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..Default::default() },)) .with_child(( ScoreText, Text::new("0"), TextFont { font: font.clone(), font_size: 64.0, ..Default::default() }, TextLayout::new_with_justify(JustifyText::Center), )); // game info, middle of the screen commands .spawn(( IntroMessageText, Node { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, ..Default::default() }, )) .with_child(( Text::new("Dodge the creeps!"), TextFont { font: font.clone(), font_size: 64.0, ..Default::default() }, TextLayout::new_with_justify(JustifyText::Center), )); commands .spawn(( StartMenuUI, Node { width: Val::Percent(100.0), height: Val::Percent(90.0), align_items: AlignItems::End, justify_content: JustifyContent::Center, ..Default::default() }, )) .with_children(|parent| { parent .spawn(( StartButton, Node { width: Val::Px(200.0), height: Val::Px(100.0), border: UiRect::all(Val::Px(5.0)), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..Default::default() }, BorderColor(Color::BLACK), BorderRadius::all(Val::Px(10.0)), BackgroundColor::from(Color::srgb(0.15, 0.15, 0.15)), )) .with_child(( Text::new("Start"), TextFont { font: font.clone(), font_size: 64.0, ..Default::default() }, TextColor::from(Color::srgb(0.9, 0.9, 0.9)), )); }); } #[derive(Component, Default)] #[require(Text)] pub struct ScoreText; #[derive(Component)] #[require(StartMenuUI, Text)] pub struct IntroMessageText; #[derive(Component)] #[require(StartMenuUI, Button)] pub struct StartButton; #[derive(Component, Default)] pub struct StartMenuUI; fn start_button_logic( current_state: Res>, mut state: ResMut>, mut score: ResMut, gamepads: Query<&Gamepad>, mut button: Query<(&Interaction, &mut BorderColor), With>, mut player_query: Query<(&mut Transform, &mut Visibility), With>, mut ui_elems_query: Query<&mut Visibility, (With, Without)>, mut score_text_query: Query<&mut Text, With>, ) { if current_state.get() == &GameState::Playing { return; }; let mut score_text = score_text_query.single_mut(); let (mut player_transform, mut player_visibility) = player_query.single_mut(); let gamepad = gamepads.get_single(); if let Ok(gamepad) = gamepad { if gamepad.just_pressed(GamepadButton::Start) { start_game( &mut score_text, &mut score, &mut state, &mut ui_elems_query, &mut player_visibility, &mut player_transform, ); return; } } let (interaction, mut border_color) = button.single_mut(); match *interaction { Interaction::Pressed => { start_game( &mut score_text, &mut score, &mut state, &mut ui_elems_query, &mut player_visibility, &mut player_transform, ); } Interaction::Hovered => border_color.0 = Color::WHITE, Interaction::None => border_color.0 = Color::BLACK, } } fn start_game( score_text: &mut Text, score: &mut Score, state: &mut NextState, ui_elems: &mut Query<&mut Visibility, (With, Without)>, player_visibility: &mut Visibility, player_transform: &mut Transform, ) { score.0 = 0; score_text.0 = format!("{}", score.0); state.set(GameState::Playing); for mut elem in ui_elems { *elem = Visibility::Hidden; } *player_visibility = Visibility::Visible; player_transform.translation = START_POSITION; }