Skip to content

Commit

Permalink
Merge pull request #102 from thombruce/feat/pause-menu
Browse files Browse the repository at this point in the history
Pause Menu
  • Loading branch information
thombruce authored Nov 14, 2023
2 parents 7adab8c + 6cfaf44 commit 8b6c803
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Actual values for semi-major axes of planetary orbits (scaled down after calculations)
- Pause menu with Continue and Exit Game buttons
- Added basic English (US) translations for pause menu
- Added basic Russian (RU) translations for pause menu
- Added basic German (DE) translations for pause menu

### Changed

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ bevy-ui-navigation = "0.33.0"
bevy_asset_loader = { version = "0.18.0", features = ["2d"] }
bevy_common_assets = { version = "0.8.0", features = ["ron"] }
bevy_fluent = "0.8.0"
bevy_picking_core = "0.17.0" # Sub-dependency of bevy-ui-navigation; we need to access one of its components
bevy_rapier2d = "0.23.0"
bevy_spatial = "0.7.0"
fluent_content = "0.0.5"
Expand Down
2 changes: 2 additions & 0 deletions assets/locales/de/de-DE/start_menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ new-game = Neues Spiel
settings = Einstellungen
credits = Credits
quit = Aufhören
continue = Weitermachen
exit-game = Spiel verlassen
2 changes: 2 additions & 0 deletions assets/locales/en/en-US/start_menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ new-game = New Game
settings = Settings
credits = Credits
quit = Quit
continue = Continue
exit-game = Exit Game
2 changes: 2 additions & 0 deletions assets/locales/ru/ru-RU/start_menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ new-game = Новая игра
settings = Настройки
credits = Кредиты
quit = Покидать
continue = Продолжать
exit-game = Выйти из игры
2 changes: 1 addition & 1 deletion src/core/resources/game_time.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bevy::{prelude::*, time::Stopwatch};

#[derive(Resource, Deref)]
pub struct GameTime(Stopwatch);
pub struct GameTime(pub Stopwatch);

pub struct GameTimePlugin;
impl Plugin for GameTimePlugin {
Expand Down
15 changes: 14 additions & 1 deletion src/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,14 @@ impl Plugin for SystemsPlugin {
),
);

// - Reset
app.add_systems(OnEnter(GameState::Reset), states::transitions::game_reset);

// - Paused
app.add_systems(OnEnter(GameState::Paused), pause::pause_screen);
app.add_systems(
OnEnter(GameState::Paused),
(pause::pause_screen, pause::toggle_physics_off),
);

// OnTransition
app.add_systems(
Expand All @@ -113,6 +119,7 @@ impl Plugin for SystemsPlugin {
OnExit(GameState::GameCreate),
hud::indicator::spawn_indicators,
);
app.add_systems(OnExit(GameState::Paused), pause::toggle_physics_on);

// FixedUpdate
// app.insert_resource(FixedTime::new_from_secs(1.0 / 60.0));
Expand All @@ -134,6 +141,12 @@ impl Plugin for SystemsPlugin {
Update,
start_menu::menu_input_system.run_if(is_in_menu_state),
);

app.add_systems(
Update,
pause::pause_input_system.run_if(in_state(GameState::Paused)),
);

app.add_systems(
Update,
start_menu::menu_focus_system
Expand Down
7 changes: 5 additions & 2 deletions src/systems/states/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@ pub enum GameState {
GameCreate,
Active,
Paused,
Reset,
}
impl GameState {
pub const IN_ANY_STATE: &[GameState; 7] = &[
pub const IN_ANY_STATE: &[GameState; 8] = &[
GameState::Loading,
GameState::LoadingTranslations,
GameState::StartMenu,
GameState::Credits,
GameState::GameCreate,
GameState::Active,
GameState::Paused,
GameState::Reset,
];
pub const IN_MENU_STATE: &[GameState; 2] = &[GameState::StartMenu, GameState::Credits];
pub const IN_MENU_STATE: &[GameState; 3] =
&[GameState::StartMenu, GameState::Credits, GameState::Paused];
pub const IN_GAME_STATE: &[GameState; 3] =
&[GameState::GameCreate, GameState::Active, GameState::Paused];
}
Expand Down
24 changes: 23 additions & 1 deletion src/systems/states/transitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use bevy::{
prelude::*,
window::Cursor,
};
use bevy_picking_core::pointer::PointerId;

use crate::core::resources::assets::AudioAssets;
use crate::core::resources::{assets::AudioAssets, game_time::GameTime};

use super::{ForState, GameState};

Expand Down Expand Up @@ -38,6 +39,27 @@ pub(crate) fn game_setup(
next_state.set(GameState::Active);
}

pub(crate) fn game_reset(
mut commands: Commands,
entities: Query<Entity, (Without<Window>, Without<Camera>, Without<PointerId>)>,
mut next_state: ResMut<NextState<GameState>>,
mut window: Query<&mut Window>,
mut game_time: ResMut<GameTime>,
) {
for entity in entities.iter() {
commands.entity(entity).despawn_recursive();
}

window.single_mut().cursor = Cursor {
visible: true,
..default()
};

game_time.0.reset();

next_state.set(GameState::Loading);
}

pub(crate) fn state_enter_despawn<T: States>(
mut commands: Commands,
state: ResMut<State<T>>,
Expand Down
74 changes: 70 additions & 4 deletions src/ui/menus/pause.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use bevy::prelude::*;
use bevy_rapier2d::prelude::RapierConfiguration;
use bevy_ui_navigation::prelude::*;
use fluent_content::Content;
use leafwing_input_manager::prelude::{ActionState, InputManagerPlugin};

use crate::{
core::{effects::blink::DrawBlinkTimer, resources::assets::UiAssets},
i18n::I18n,
inputs::pause::{pause_input_map, PauseAction},
inputs::{
menu::MenuAction,
pause::{pause_input_map, PauseAction},
},
systems::states::{ForState, GameState},
};

Expand All @@ -17,6 +21,12 @@ impl Plugin for PausePlugin {
}
}

#[derive(Component)]
pub enum MenuButton {
Continue,
ExitGame,
}

pub(crate) fn setup_pause_systems(mut commands: Commands) {
commands.insert_resource(pause_input_map());
commands.insert_resource(ActionState::<PauseAction>::default());
Expand All @@ -26,23 +36,28 @@ pub(crate) fn pause_system(
state: Res<State<GameState>>,
mut next_state: ResMut<NextState<GameState>>,
pause_action_state: Res<ActionState<PauseAction>>,
mut rapier_configuration: ResMut<RapierConfiguration>,
) {
if pause_action_state.just_pressed(PauseAction::Pause) {
match state.get() {
GameState::Active => {
next_state.set(GameState::Paused);
rapier_configuration.physics_pipeline_active = false;
}
GameState::Paused => {
next_state.set(GameState::Active);
rapier_configuration.physics_pipeline_active = true;
}
_ => {}
}
}
}

pub(crate) fn toggle_physics_on(mut rapier_configuration: ResMut<RapierConfiguration>) {
rapier_configuration.physics_pipeline_active = true;
}

pub(crate) fn toggle_physics_off(mut rapier_configuration: ResMut<RapierConfiguration>) {
rapier_configuration.physics_pipeline_active = false;
}

pub(crate) fn pause_screen(mut commands: Commands, ui: Res<UiAssets>, i18n: Res<I18n>) {
commands
.spawn((
Expand Down Expand Up @@ -78,5 +93,56 @@ pub(crate) fn pause_screen(mut commands: Commands, ui: Res<UiAssets>, i18n: Res<
},
DrawBlinkTimer(Timer::from_seconds(0.65, TimerMode::Repeating)),
));

for (string, marker) in [
("continue", MenuButton::Continue),
("exit-game", MenuButton::ExitGame),
] {
parent.spawn((
TextBundle {
text: Text::from_section(
i18n.content(string).unwrap().to_ascii_uppercase(),
TextStyle {
font: ui.font.clone(),
font_size: 25.0,
color: Color::rgb_u8(0x00, 0x88, 0x88),
},
),
style: Style {
margin: UiRect::top(Val::Px(25.)),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..default()
},
..default()
}, // DrawBlinkTimer(Timer::from_seconds(0.65, TimerMode::Repeating)),
Focusable::default(),
marker,
));
}
});
}

pub(crate) fn pause_input_system(
mut next_state: ResMut<NextState<GameState>>,
inputs: Res<ActionState<MenuAction>>,
mut requests: EventWriter<NavRequest>,
mut buttons: Query<&mut MenuButton>,
mut events: EventReader<NavEvent>,
) {
events.nav_iter().activated_in_query_foreach_mut(
&mut buttons,
|mut button| match &mut *button {
MenuButton::Continue => {
next_state.set(GameState::Active);
}
MenuButton::ExitGame => {
next_state.set(GameState::Reset);
}
},
);

if inputs.just_pressed(MenuAction::Select) {
requests.send(NavRequest::Action);
}
}
2 changes: 2 additions & 0 deletions src/ui/menus/start_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ pub(crate) fn menu_input_system(
if inputs.just_pressed(MenuAction::Start) {
next_state.set(GameState::GameCreate);
}

// TODO: We shouldn't be able to access credits from pause state
if inputs.just_released(MenuAction::Credits) {
match state.get() {
GameState::StartMenu => {
Expand Down

0 comments on commit 8b6c803

Please sign in to comment.