menu.rs (3158B)
1 use crate::loading::FontAssets; 2 use crate::GameState; 3 use bevy::prelude::*; 4 5 pub struct MenuPlugin; 6 7 /// This plugin is responsible for the game menu (containing only one button...) 8 /// The menu is only drawn during the State `GameState::Menu` and is removed when that state is exited 9 impl Plugin for MenuPlugin { 10 fn build(&self, app: &mut App) { 11 app.init_resource::<ButtonColors>() 12 .add_system_set(SystemSet::on_enter(GameState::Menu).with_system(setup_menu.system())) 13 .add_system_set( 14 SystemSet::on_update(GameState::Menu).with_system(click_play_button.system()), 15 ); 16 } 17 } 18 19 struct ButtonColors { 20 normal: UiColor, 21 hovered: UiColor, 22 } 23 24 impl Default for ButtonColors { 25 fn default() -> Self { 26 ButtonColors { 27 normal: Color::rgb(0.15, 0.15, 0.15).into(), 28 hovered: Color::rgb(0.25, 0.25, 0.25).into(), 29 } 30 } 31 } 32 33 #[derive(Component)] 34 struct PlayButton; 35 36 fn setup_menu( 37 mut commands: Commands, 38 font_assets: Res<FontAssets>, 39 button_colors: Res<ButtonColors>, 40 ) { 41 commands.spawn_bundle(UiCameraBundle::default()); 42 commands 43 .spawn_bundle(ButtonBundle { 44 style: Style { 45 size: Size::new(Val::Px(120.0), Val::Px(50.0)), 46 margin: Rect::all(Val::Auto), 47 justify_content: JustifyContent::Center, 48 align_items: AlignItems::Center, 49 ..Default::default() 50 }, 51 color: button_colors.normal, 52 ..Default::default() 53 }) 54 .insert(PlayButton) 55 .with_children(|parent| { 56 parent.spawn_bundle(TextBundle { 57 text: Text { 58 sections: vec![TextSection { 59 value: "Play".to_string(), 60 style: TextStyle { 61 font: font_assets.fira_sans.clone(), 62 font_size: 40.0, 63 color: Color::rgb(0.9, 0.9, 0.9), 64 }, 65 }], 66 alignment: Default::default(), 67 }, 68 ..Default::default() 69 }); 70 }); 71 } 72 73 type ButtonInteraction<'a> = (Entity, &'a Interaction, &'a mut UiColor, &'a Children); 74 75 fn click_play_button( 76 mut commands: Commands, 77 button_colors: Res<ButtonColors>, 78 mut state: ResMut<State<GameState>>, 79 mut interaction_query: Query<ButtonInteraction, (Changed<Interaction>, With<Button>)>, 80 text_query: Query<Entity, With<Text>>, 81 ) { 82 for (button, interaction, mut color, children) in interaction_query.iter_mut() { 83 let text = text_query.get(children[0]).unwrap(); 84 match *interaction { 85 Interaction::Clicked => { 86 commands.entity(button).despawn(); 87 commands.entity(text).despawn(); 88 state.set(GameState::Playing).unwrap(); 89 } 90 Interaction::Hovered => { 91 *color = button_colors.hovered; 92 } 93 Interaction::None => { 94 *color = button_colors.normal; 95 } 96 } 97 } 98 }