main menu works!

main
Elijah C. Voigt 2 years ago
parent 4b5c90f1ba
commit 3091a15dea

@ -23,6 +23,7 @@ fn init_credits_ui(mut commands: Commands) {
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
position_type: PositionType::Absolute,
flex_direction: FlexDirection::Column,
..default()
},
visibility: Visibility::Hidden,
@ -32,16 +33,59 @@ fn init_credits_ui(mut commands: Commands) {
.with_children(|parent| {
parent.spawn((
Credits,
TextBundle {
text: Text {
alignment: TextAlignment::Center,
sections: vec![],
NodeBundle {
style: Style {
padding: UiRect::all(Val::Px(25.0)),
..default()
},
background_color: Color::BLACK.with_a(0.5).into(),
..default()
},
));
}
)).with_children(|parent| {
parent.spawn((
Credits,
TextBundle {
text: Text {
alignment: TextAlignment::Center,
sections: vec![],
..default()
},
..default()
},
));
});
parent
.spawn((
menu::ButtonAction(GameState::Play),
menu::ButtonAction(menu::MenuState::Play),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
margin: UiRect::all(Val::Px(5.0)),
..default()
},
background_color: Color::ORANGE.with_a(0.5).into(),
..default()
},
))
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text {
sections: vec![TextSection {
value: "Back".into(),
style: TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
}],
..default()
},
..default()
});
});
});
}

@ -1,3 +1,4 @@
use bevy::app::AppExit;
use bevy::utils::HashSet;
use crate::audio::AudioEvent;
@ -44,7 +45,8 @@ impl Plugin for GamePlugin {
.add_systems(
PostUpdate,
(debug_board.run_if(resource_exists::<debug::DebugEnabled>()),),
);
)
.add_systems(OnEnter(GameState::Quit), handle_quit);
}
}
@ -842,3 +844,11 @@ fn reset_game(
.remove::<Captured>();
});
}
/// Very simple system to handle the "Quit" state (shutdown the game)
fn handle_quit(
mut app_exit_events: EventWriter<AppExit>,
) {
app_exit_events.send(AppExit);
}

@ -74,6 +74,8 @@ pub enum GameState {
Intro,
Play,
Endgame,
Restart,
Quit,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States, Component)]

@ -1,5 +1,3 @@
use bevy::app::AppExit;
use crate::prelude::*;
use self::tutorial::TutorialState;
@ -19,16 +17,17 @@ impl Plugin for MenuPlugin {
Update,
manage_state_entities::<MenuState>().run_if(state_changed::<MenuState>()),
)
.add_systems(
Update,
handle_button_press.run_if(any_component_changed::<Interaction>()),
)
.add_systems(Update, (
handle_button_press::<GameState>,
handle_button_press::<MenuState>,
handle_button_press::<TutorialState>,
).run_if(any_component_changed::<Interaction>()))
.add_systems(Update, set_menu_state.run_if(just_pressed(KeyCode::Escape)));
}
}
#[derive(Debug, States, Hash, Default, PartialEq, Eq, Clone, Component)]
enum MenuState {
pub(crate) enum MenuState {
#[default]
None,
Play,
@ -37,13 +36,7 @@ enum MenuState {
}
#[derive(Debug, Component)]
enum ButtonAction {
GameState(GameState),
MenuState(MenuState),
TutorialState(tutorial::TutorialState),
Restart,
Quit,
}
pub(crate) struct ButtonAction<S: States + Clone + Component>(pub S);
fn init_play_menu(mut commands: Commands) {
info!("Initializing Play menu");
@ -80,7 +73,8 @@ fn init_play_menu(mut commands: Commands) {
// Continue button
parent
.spawn((
ButtonAction::MenuState(MenuState::None),
ButtonAction(GameState::Play),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -105,7 +99,8 @@ fn init_play_menu(mut commands: Commands) {
// Tutorial button
parent
.spawn((
ButtonAction::TutorialState(tutorial::TutorialState::Intro),
ButtonAction(tutorial::TutorialState::Intro),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -130,7 +125,8 @@ fn init_play_menu(mut commands: Commands) {
// Credits button
parent
.spawn((
ButtonAction::GameState(GameState::Credits),
ButtonAction(GameState::Credits),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -155,7 +151,8 @@ fn init_play_menu(mut commands: Commands) {
// Quit button
parent
.spawn((
ButtonAction::Quit,
ButtonAction(GameState::Quit),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -202,7 +199,8 @@ fn init_tutorial_menu(mut commands: Commands) {
// Continue button
parent
.spawn((
ButtonAction::MenuState(MenuState::None),
ButtonAction(GameState::Play),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -227,7 +225,8 @@ fn init_tutorial_menu(mut commands: Commands) {
// Quit button
parent
.spawn((
ButtonAction::Restart,
ButtonAction(GameState::Restart),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -271,10 +270,11 @@ fn init_endgame_menu(mut commands: Commands) {
},
))
.with_children(|parent| {
// Continue button
// New Game button
parent
.spawn((
ButtonAction::Restart,
ButtonAction(GameState::Restart),
ButtonAction(MenuState::None),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -299,7 +299,8 @@ fn init_endgame_menu(mut commands: Commands) {
// Quit button
parent
.spawn((
ButtonAction::Quit,
ButtonAction(MenuState::None),
ButtonAction(GameState::Quit),
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(5.0)),
@ -333,26 +334,20 @@ fn set_menu_state(
GameState::Endgame => next_menu_state.set(MenuState::Endgame),
GameState::Intro => error!("Should skip to GameState::Play"),
GameState::Credits => error!("Should pop back to GameState::Play"),
GameState::Restart | GameState::Quit => panic!("This shouldn't be possible!"),
}
}
fn handle_button_press(
events: Query<(&Interaction, &ButtonAction), Changed<Interaction>>,
mut next_game_state: ResMut<NextState<GameState>>,
mut next_tutorial_state: ResMut<NextState<TutorialState>>,
mut next_menu_state: ResMut<NextState<MenuState>>,
mut app_exit_events: EventWriter<AppExit>,
fn handle_button_press<S: States + Clone + Component>(
events: Query<(&Interaction, &ButtonAction<S>), Changed<Interaction>>,
mut next_state: ResMut<NextState<S>>,
) {
events
.iter()
.filter_map(|(interaction, button_action)| {
(*interaction == Interaction::Pressed).then_some(button_action)
})
.for_each(|button_action| match button_action {
ButtonAction::GameState(gs) => next_game_state.set(gs.clone()),
ButtonAction::MenuState(ms) => next_menu_state.set(ms.clone()),
ButtonAction::TutorialState(ts) => next_tutorial_state.set(ts.clone()),
ButtonAction::Quit => app_exit_events.send(AppExit),
ButtonAction::Restart => panic!("TODO: Restart game!"),
.for_each(|ButtonAction(ba)| {
next_state.set(ba.clone())
});
}

Loading…
Cancel
Save