Saving my place

Adding a little 'just_pressed' helper for system conditionals
Replaces that lambda I kept using all over the place
main
Elijah C. Voigt 2 years ago
parent ca092ddbc0
commit 5fc0706c10

@ -29,8 +29,7 @@ impl Plugin for AudioPlugin {
play_audio.run_if(any_component_added::<AudioSource>), play_audio.run_if(any_component_added::<AudioSource>),
audio_trigger.run_if(on_event::<AudioEvent>()), audio_trigger.run_if(on_event::<AudioEvent>()),
control_volume.run_if(resource_changed::<AudioVolume>()), control_volume.run_if(resource_changed::<AudioVolume>()),
toggle_volume toggle_volume.run_if(just_pressed(KeyCode::M)),
.run_if(|keys: Res<Input<KeyCode>>| -> bool { keys.just_pressed(KeyCode::M) }),
), ),
); );
} }

@ -84,9 +84,7 @@ impl Plugin for Display3dPlugin {
setup_capture_piece.run_if(any_component_changed::<Handle<StandardMaterial>>), setup_capture_piece.run_if(any_component_changed::<Handle<StandardMaterial>>),
capture_piece.run_if(any_with_component::<game::Captured>()), capture_piece.run_if(any_with_component::<game::Captured>()),
skip_animation skip_animation
.run_if(|keys: Res<Input<KeyCode>>| -> bool { .run_if(just_pressed(KeyCode::Return))
keys.just_pressed(KeyCode::Return)
})
.run_if(in_state(GameState::Play)), .run_if(in_state(GameState::Play)),
), ),
) )

@ -24,17 +24,13 @@ impl Plugin for GamePlugin {
.run_if(on_event::<Move>()) .run_if(on_event::<Move>())
.after(handle_selection), .after(handle_selection),
set_side.run_if(any_component_changed::<BoardIndex>), set_side.run_if(any_component_changed::<BoardIndex>),
cancel_place.run_if(|buttons: Res<Input<MouseButton>>| -> bool { cancel_place.run_if(just_pressed(MouseButton::Right)),
buttons.just_pressed(MouseButton::Right)
}),
handle_selection.run_if(on_event::<Selection>()), handle_selection.run_if(on_event::<Selection>()),
show_valid_moves.run_if(any_component_added::<Selected>), show_valid_moves.run_if(any_component_added::<Selected>),
hide_valid_moves.run_if(any_component_removed::<Selected>()), hide_valid_moves.run_if(any_component_removed::<Selected>()),
manage_score.run_if(any_component_added::<Captured>), manage_score.run_if(any_component_added::<Captured>),
check_endgame.run_if(resource_changed::<Board>()), check_endgame.run_if(resource_changed::<Board>()),
reset_game.run_if(|keys: Res<Input<KeyCode>>| -> bool { reset_game.run_if(just_pressed(KeyCode::R)),
keys.just_pressed(KeyCode::R)
}),
), ),
) )
.add_systems(OnEnter(GameState::Endgame), set_endgame) .add_systems(OnEnter(GameState::Endgame), set_endgame)

@ -23,11 +23,7 @@ impl Plugin for IntroPlugin {
// Started when the TextScrollAnimation component is added to the parent entity // Started when the TextScrollAnimation component is added to the parent entity
// Updated for as long as there is scrolling text // Updated for as long as there is scrolling text
manage_scroll_text_animation.run_if( manage_scroll_text_animation.run_if(
any_component_added::<ui::TextScrollAnimation>.or_else( any_component_added::<ui::TextScrollAnimation>.or_else(just_pressed(KeyCode::Return)),
|keys: Res<Input<KeyCode>>| -> bool {
keys.just_pressed(KeyCode::Return)
},
),
), ),
// Play intro manages playing the intro of each individual paragraph // Play intro manages playing the intro of each individual paragraph
// Runs every time the TextScroll component (managed by manage_scroll_text_animation) is updated // Runs every time the TextScroll component (managed by manage_scroll_text_animation) is updated

@ -17,7 +17,7 @@ mod tweak;
mod ui; mod ui;
use bevy::winit::WinitWindows; use bevy::winit::WinitWindows;
use std::time::Duration; use std::{hash::Hash, time::Duration};
use winit::window::Icon; use winit::window::Icon;
use crate::prelude::*; use crate::prelude::*;
@ -162,3 +162,13 @@ fn set_window_icon(
window.set_window_icon(Some(icon.clone())); window.set_window_icon(Some(icon.clone()));
} }
} }
pub(crate) fn just_pressed<T>(button: T) -> impl FnMut(Res<Input<T>>) -> bool + Clone
where
T: Copy + Eq + Hash + Send + Sync + 'static
{
Box::new(move |buttons: Res<Input<T>>| -> bool {
buttons.just_pressed(button)
})
}

@ -1,7 +1,7 @@
use bevy::ecs::system::EntityCommands;
use crate::prelude::*; use crate::prelude::*;
use self::tutorial::TutorialState;
pub(crate) struct MenuPlugin; pub(crate) struct MenuPlugin;
impl Plugin for MenuPlugin { impl Plugin for MenuPlugin {
@ -16,6 +16,10 @@ impl Plugin for MenuPlugin {
.add_systems( .add_systems(
Update, Update,
manage_state_entities::<MenuState>().run_if(state_changed::<MenuState>()), manage_state_entities::<MenuState>().run_if(state_changed::<MenuState>()),
)
.add_systems(
Update,
set_menu_state.run_if(just_pressed(KeyCode::Escape))
); );
} }
} }
@ -29,6 +33,15 @@ enum MenuState {
Endgame, Endgame,
} }
#[derive(Debug, Component)]
enum ButtonAction {
GameState(GameState),
MenuState(MenuState),
TutorialState(tutorial::TutorialState),
Restart,
Quit,
}
fn init_play_menu(mut commands: Commands) { fn init_play_menu(mut commands: Commands) {
info!("Initializing Play menu"); info!("Initializing Play menu");
@ -51,8 +64,8 @@ fn init_play_menu(mut commands: Commands) {
}, },
)) ))
.with_children(|parent| { .with_children(|parent| {
// Title
parent.spawn(( parent.spawn((
MenuState::Play,
TextBundle::from_section( TextBundle::from_section(
"M A R T I A N C H E S S", "M A R T I A N C H E S S",
TextStyle { TextStyle {
@ -62,10 +75,11 @@ fn init_play_menu(mut commands: Commands) {
}, },
), ),
)); ));
// Continue button
parent parent
.spawn(( .spawn((
GameState::Play, ButtonAction::MenuState(MenuState::None),
MenuState::None,
ButtonBundle { ButtonBundle {
style: Style { style: Style {
padding: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)),
@ -78,8 +92,6 @@ fn init_play_menu(mut commands: Commands) {
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
GameState::Play,
MenuState::None,
TextBundle::from_section( TextBundle::from_section(
"Continue", "Continue",
TextStyle { TextStyle {
@ -91,10 +103,37 @@ fn init_play_menu(mut commands: Commands) {
)); ));
}); });
// Tutorial button
parent
.spawn((
ButtonAction::TutorialState(tutorial::TutorialState::Intro),
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::from_section(
"Tutorial",
TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
),
));
});
// Credits button
parent parent
.spawn(( .spawn((
GameState::Credits, ButtonAction::GameState(GameState::Credits),
MenuState::None,
ButtonBundle { ButtonBundle {
style: Style { style: Style {
padding: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)),
@ -107,8 +146,6 @@ fn init_play_menu(mut commands: Commands) {
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn(( parent.spawn((
GameState::Credits,
MenuState::None,
TextBundle::from_section( TextBundle::from_section(
"Credits", "Credits",
TextStyle { TextStyle {
@ -120,8 +157,11 @@ fn init_play_menu(mut commands: Commands) {
)); ));
}); });
// Quit button
parent parent
.spawn((ButtonBundle { .spawn((
ButtonAction::Quit,
ButtonBundle {
style: Style { style: Style {
padding: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)),
margin: UiRect::all(Val::Px(5.0)), margin: UiRect::all(Val::Px(5.0)),
@ -140,32 +180,75 @@ fn init_play_menu(mut commands: Commands) {
}, },
),)); ),));
}); });
});
}
fn init_tutorial_menu(mut commands: Commands) {
commands
.spawn((
MenuState::Tutorial,
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
flex_direction: FlexDirection::Column,
position_type: PositionType::Absolute,
..default()
},
background_color: Color::NONE.into(),
visibility: Visibility::Hidden,
..default()
},
))
.with_children(|parent| {
// Continue button
parent parent
.spawn(( .spawn((
tutorial::TutorialState::Intro, // Marks the button to start the tutorial ButtonAction::MenuState(MenuState::None),
GameState::Play, // Marks the button to be ignored during tutorial step cleanup
MenuState::None,
ButtonBundle { ButtonBundle {
style: Style { style: Style {
padding: UiRect::all(Val::Px(5.0)), padding: UiRect::all(Val::Px(5.0)),
margin: UiRect::all(Val::Px(5.0)), margin: UiRect::all(Val::Px(5.0)),
position_type: PositionType::Absolute,
top: Val::Px(0.0),
right: Val::Px(0.0),
..default() ..default()
}, },
background_color: Color::ORANGE.with_a(0.5).into(), background_color: Color::ORANGE.with_a(0.5).into(),
visibility: Visibility::Hidden,
..default() ..default()
}, },
)) ))
.with_children(|parent| {
parent.spawn((
TextBundle::from_section(
"Continue Game",
TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
),
));
});
// Quit button
parent
.spawn((
ButtonAction::Restart,
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| { .with_children(|parent| {
parent.spawn((TextBundle::from_section( parent.spawn((TextBundle::from_section(
"Tutorial", "Restart",
TextStyle { TextStyle {
color: Color::BLACK, color: Color::BLACK,
font_size: 16.0, font_size: 32.0,
..default() ..default()
}, },
),)); ),));
@ -173,10 +256,89 @@ fn init_play_menu(mut commands: Commands) {
}); });
} }
fn init_tutorial_menu(mut commands: Commands) {
error!("Tutorial Menu");
}
fn init_endgame_menu(mut commands: Commands) { fn init_endgame_menu(mut commands: Commands) {
error!("Endgame Menu"); commands
.spawn((
MenuState::Endgame,
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
flex_direction: FlexDirection::Column,
position_type: PositionType::Absolute,
..default()
},
background_color: Color::NONE.into(),
visibility: Visibility::Hidden,
..default()
},
))
.with_children(|parent| {
// Continue button
parent
.spawn((
ButtonAction::Restart,
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::from_section(
"New Game",
TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
),
));
});
// Quit button
parent
.spawn((
ButtonAction::Quit,
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::from_section(
"Quit",
TextStyle {
color: Color::BLACK,
font_size: 32.0,
..default()
},
),));
});
});
} }
fn set_menu_state(
game_state: Res<State<GameState>>,
mut next_menu_state: ResMut<NextState<MenuState>>,
) {
match game_state.get() {
GameState::Loading => error!("No menu while loading!"),
GameState::Play => next_menu_state.set(MenuState::Play),
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")
}
}

@ -27,9 +27,7 @@ impl Plugin for TutorialPlugin {
// A piece is de-selected // A piece is de-selected
.or_else(any_component_removed::<game::Selected>()) .or_else(any_component_removed::<game::Selected>())
// TEMP: The user hits 'enter' // TEMP: The user hits 'enter'
.or_else(|keys: Res<Input<KeyCode>>| -> bool { .or_else(just_pressed(KeyCode::Return)),
keys.just_pressed(KeyCode::Return)
}),
), ),
), ),
), ),

Loading…
Cancel
Save