Skip to content

Commit

Permalink
Merge pull request #103 from thombruce/feat/game-over
Browse files Browse the repository at this point in the history
Game Over
  • Loading branch information
thombruce authored Nov 15, 2023
2 parents 8b6c803 + 04985cb commit 9dc800f
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 20 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- 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
- Game Over screen on player death
- Added basic English (US) translations for pause menu and game over screen
- Added basic Russian (RU) translations for pause menu and game over screen
- Added basic German (DE) translations for pause menu and game over screen

### Changed

Expand Down
3 changes: 3 additions & 0 deletions assets/locales/de/de-DE/game.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ near = In der Nähe von { $celestial ->
# Pause
pause = Pause
# Game Over
game-over = Spiel Vorbei
# Datetime
# TODO: Pass date and time as a workable datetime value for translation
# time = { DATETIME($datetime) }
3 changes: 3 additions & 0 deletions assets/locales/en/en-US/game.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ near = Near { $celestial ->
# Pause
pause = Pause
# Game Over
game-over = Game Over
# Datetime
# TODO: Pass date and time as a workable datetime value for translation
# time = { DATETIME($datetime) }
3 changes: 3 additions & 0 deletions assets/locales/ru/ru-RU/game.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ near = Рядом с { $celestial ->
# Pause
pause = Пауза
# Game Over
game-over = Игра закончена
# Datetime
# TODO: Pass date and time as a workable datetime value for translation
# time = { DATETIME($datetime) }
13 changes: 12 additions & 1 deletion src/ships/ship.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;

use crate::systems::events::BulletShipContactEvent;
use crate::systems::{events::BulletShipContactEvent, states::GameState};

use super::player::Player;

/// Ship component
#[derive(Component)]
Expand Down Expand Up @@ -64,3 +66,12 @@ pub(crate) fn ship_damage(
}
}
}

pub(crate) fn game_over(
player: Query<Entity, With<Player>>,
mut next_state: ResMut<NextState<GameState>>,
) {
if player.is_empty() {
next_state.set(GameState::GameOver);
}
}
35 changes: 24 additions & 11 deletions src/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ use crate::{
temp,
ui::{
camera, damage, hud,
menus::{credits, pause, start_menu},
menus::{credits, game_over, pause, start_menu},
},
world::astronomy::{self, planetary_system, starfield},
};

use self::{
states::{is_in_game_state, is_in_menu_state, GameState},
states::{is_in_active_state, is_in_game_state, is_in_menu_state, GameState},
system_sets::{AttackSet, MovementSet},
};

Expand Down Expand Up @@ -97,6 +97,9 @@ impl Plugin for SystemsPlugin {
(pause::pause_screen, pause::toggle_physics_off),
);

// - Game Over
app.add_systems(OnEnter(GameState::GameOver), game_over::game_over_screen);

// OnTransition
app.add_systems(
OnTransition {
Expand Down Expand Up @@ -147,6 +150,11 @@ impl Plugin for SystemsPlugin {
pause::pause_input_system.run_if(in_state(GameState::Paused)),
);

app.add_systems(
Update,
game_over::game_over_input_system.run_if(in_state(GameState::GameOver)),
);

app.add_systems(
Update,
start_menu::menu_focus_system
Expand Down Expand Up @@ -184,20 +192,25 @@ impl Plugin for SystemsPlugin {
// The SystemSets aren't aware of one another, they need to be configured.
// Reassess and order systems appropriately.
enemy::enemy_targeting_system.before(ship::ship_damage),
(player::player_flight_system, enemy::enemy_flight_system).in_set(MovementSet),
(bullet::spawn_bullet, camera::follow_player).after(MovementSet),
(
enemy::enemy_weapons_system,
player::player_weapons_system,
events::contact_system,
)
.in_set(AttackSet),
enemy::enemy_flight_system.in_set(MovementSet),
bullet::spawn_bullet.after(MovementSet),
(enemy::enemy_weapons_system, events::contact_system).in_set(AttackSet),
(
ship::ship_damage,
damage::ui_spawn_damage,
damage::ui_text_fade_out,
)
.after(AttackSet),
)
.run_if(is_in_active_state),
);

app.add_systems(
Update,
(
player::player_flight_system.in_set(MovementSet),
camera::follow_player.after(MovementSet),
player::player_weapons_system.in_set(AttackSet),
)
.run_if(in_state(GameState::Active)),
);
Expand All @@ -209,6 +222,6 @@ impl Plugin for SystemsPlugin {
);

// Last
// app.add_systems(Last, _);
app.add_systems(Last, ship::game_over.run_if(in_state(GameState::Active)));
}
}
25 changes: 20 additions & 5 deletions src/systems/states/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,34 @@ pub enum GameState {
GameCreate,
Active,
Paused,
GameOver,
Reset,
}
impl GameState {
pub const IN_ANY_STATE: &[GameState; 8] = &[
pub const IN_ANY_STATE: &[GameState; 9] = &[
GameState::Loading,
GameState::LoadingTranslations,
GameState::StartMenu,
GameState::Credits,
GameState::GameCreate,
GameState::Active,
GameState::Paused,
GameState::GameOver,
GameState::Reset,
];
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];
pub const IN_MENU_STATE: &[GameState; 4] = &[
GameState::StartMenu,
GameState::Credits,
GameState::Paused,
GameState::GameOver,
];
pub const IN_GAME_STATE: &[GameState; 4] = &[
GameState::GameCreate,
GameState::Active,
GameState::Paused,
GameState::GameOver,
];
pub const IN_ACTIVE_STATE: &[GameState; 2] = &[GameState::Active, GameState::GameOver];
}

pub fn is_in_menu_state(state: Res<State<GameState>>) -> bool {
Expand All @@ -41,6 +52,10 @@ pub fn is_in_game_state(state: Res<State<GameState>>) -> bool {
GameState::IN_GAME_STATE.contains(state.get())
}

pub fn is_in_active_state(state: Res<State<GameState>>) -> bool {
GameState::IN_ACTIVE_STATE.contains(state.get())
}

/// Component to tag an entity as only needed in some of the states
#[derive(Component, Debug)]
pub struct ForState<T> {
Expand Down
107 changes: 107 additions & 0 deletions src/ui/menus/game_over.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use bevy::{app::AppExit, prelude::*};
use bevy_ui_navigation::prelude::*;
use fluent_content::Content;
use leafwing_input_manager::prelude::ActionState;

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

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

pub(crate) fn game_over_screen(mut commands: Commands, ui: Res<UiAssets>, i18n: Res<I18n>) {
commands
.spawn((
NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
flex_direction: FlexDirection::Column,
..default()
},
background_color: BackgroundColor(Color::rgba(0., 0., 0., 0.65)),
..default()
},
ForState {
states: vec![GameState::GameOver],
},
))
.with_children(|parent| {
parent.spawn((
TextBundle {
style: Style { ..default() },
text: Text::from_section(
i18n.content("game-over").unwrap().to_ascii_uppercase(),
TextStyle {
font: ui.font.clone(),
font_size: 50.0,
color: Color::rgb_u8(0x88, 0x00, 0x00),
},
),
..default()
},
DrawBlinkTimer(Timer::from_seconds(0.65, TimerMode::Repeating)),
));

for (string, marker) in [
("exit-game", MenuButton::ExitGame),
("quit", MenuButton::Quit),
] {
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 game_over_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>,
mut exit: EventWriter<AppExit>,
) {
events.nav_iter().activated_in_query_foreach_mut(
&mut buttons,
|mut button| match &mut *button {
MenuButton::ExitGame => {
next_state.set(GameState::Reset);
}
MenuButton::Quit => {
exit.send(AppExit);
}
},
);

if inputs.just_pressed(MenuAction::Select) {
requests.send(NavRequest::Action);
}
}
1 change: 1 addition & 0 deletions src/ui/menus/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod credits;
pub mod game_over;
pub mod pause;
pub mod start_menu;

0 comments on commit 9dc800f

Please sign in to comment.