|
|
|
|
@ -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())
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|