Skip to content

Commit

Permalink
added victory and defeat screens
Browse files Browse the repository at this point in the history
  • Loading branch information
ramirezmike committed Jul 28, 2024
1 parent 8bdc26f commit cd5cc93
Show file tree
Hide file tree
Showing 4 changed files with 329 additions and 3 deletions.
14 changes: 12 additions & 2 deletions src/screen/playing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod defeat_menu;
pub mod hud;
pub mod level_up_menu;
pub mod pause_menu;
pub mod victory_menu;

use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
Expand All @@ -20,19 +22,25 @@ use crate::game::wave::wave;
use crate::game::GameRoot;
use crate::screen::fade_in;
use crate::screen::playing::hud::playing_hud;
use crate::screen::playing::victory_menu::reset_endless_mode;
use crate::screen::Screen;
use crate::ui::prelude::*;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.add_systems(
StateFlush,
Screen::Playing.on_edge(stop_music, (enter_playing, start_music)),
Screen::Playing.on_edge(stop_music, (enter_playing, start_music, reset_endless_mode)),
);

app.configure::<(PlayingAssets, PlayingAction, PlayingMenu)>();

app.add_plugins((level_up_menu::plugin, pause_menu::plugin));
app.add_plugins((
level_up_menu::plugin,
pause_menu::plugin,
victory_menu::plugin,
defeat_menu::plugin,
));
}

fn enter_playing(mut commands: Commands, game_root: Res<GameRoot>, ui_root: Res<UiRoot>) {
Expand Down Expand Up @@ -138,6 +146,8 @@ impl Configure for PlayingAction {
enum PlayingMenu {
Pause,
LevelUp,
Victory,
Defeat,
}

impl Configure for PlayingMenu {
Expand Down
138 changes: 138 additions & 0 deletions src/screen/playing/defeat_menu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use bevy::prelude::*;
use bevy_kira_audio::prelude::*;
use bevy_mod_picking::prelude::*;
use pyri_state::extra::entity_scope::StateScope;
use pyri_state::prelude::*;

use crate::core::pause::Pause;
use crate::core::UpdateSet;
use crate::game::actor::player::IsPlayer;
use crate::screen::fade_out;
use crate::screen::playing::PlayingAssets;
use crate::screen::playing::PlayingMenu;
use crate::screen::Screen;
use crate::ui::prelude::*;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.add_systems(
StateFlush,
PlayingMenu::Defeat.on_edge(Pause::disable, (Pause::enable_default, open_defeat_menu)),
);

app.add_systems(
Update,
PlayingMenu::Defeat
.enter()
.in_set(UpdateSet::SyncLate)
.run_if(detect_defeat),
);
}

fn open_defeat_menu(mut commands: Commands, ui_root: Res<UiRoot>) {
commands.spawn_with(defeat_overlay).set_parent(ui_root.body);
commands.spawn_with(defeat_menu).set_parent(ui_root.body);
}

pub fn detect_defeat(player_query: Query<Entity, With<IsPlayer>>) -> bool {
player_query.is_empty()
}

fn defeat_overlay(mut entity: EntityWorldMut) {
entity.add(widget::blocking_overlay).insert((
Name::new("DefeatOverlay"),
ZIndex::Global(1),
ThemeColor::Overlay.target::<BackgroundColor>(),
StateScope::<PlayingMenu>::default(),
));
}

fn defeat_menu(mut entity: EntityWorldMut) {
entity
.insert((
Name::new("DefeatMenu"),
NodeBundle {
style: Style::ABS_COLUMN_MID,
z_index: ZIndex::Global(2),
..default()
},
StateScope::<PlayingMenu>::default(),
))
.with_children(|children| {
children.spawn_with(header);
children.spawn_with(button_container);
});
}

const HEADER: &str = "Defeat :(";

fn header(mut entity: EntityWorldMut) {
entity.insert((
Name::new("Header"),
TextBundle::from_section(
HEADER,
TextStyle {
font: BOLD_FONT_HANDLE,
..default()
},
)
.with_style(Style {
margin: UiRect::top(Vw(4.5)),
..default()
}),
DynamicFontSize::new(Vw(5.0)).with_step(8.0),
ThemeColorForText(vec![ThemeColor::BodyText]),
));
}

fn button_container(mut entity: EntityWorldMut) {
entity
.insert((
Name::new("ButtonContainer"),
NodeBundle {
style: Style {
align_items: AlignItems::Center,
flex_direction: FlexDirection::Column,
margin: UiRect::top(VMin(6.0)),
row_gap: Vw(2.5),
..default()
},
..default()
},
))
.with_children(|children| {
children.spawn_with(restart_button);
children.spawn_with(quit_to_title_button);
});
}

fn restart_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Restart")).insert((
On::<Pointer<Click>>::run(
|mut commands: Commands, audio: Res<Audio>, assets: Res<PlayingAssets>| {
audio.play(assets.sfx_restart.clone()).with_volume(0.7);
commands.spawn_with(fade_out(Screen::Playing));
},
),
Style {
height: Vw(9.0),
width: Vw(38.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
));
}

fn quit_to_title_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Quit to title")).insert((
On::<Pointer<Click>>::run(Screen::Title.enter()),
Style {
height: Vw(9.0),
width: Vw(38.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
));
}
3 changes: 2 additions & 1 deletion src/screen/playing/level_up_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::game::card::card;
use crate::game::card::deck::Deck;
use crate::game::card::deck::IsDeckDisplay;
use crate::game::card::CardConfig;
use crate::screen::playing::victory_menu::detect_victory;
use crate::screen::playing::PlayingAssets;
use crate::screen::playing::PlayingMenu;
use crate::ui::prelude::*;
Expand All @@ -32,7 +33,7 @@ pub(super) fn plugin(app: &mut App) {
PlayingMenu::LevelUp
.enter()
.in_set(UpdateSet::SyncLate)
.run_if(on_event::<LevelUp>()),
.run_if(on_event::<LevelUp>().and_then(not(detect_victory))),
);

app.configure::<(LevelUpMenuAction, ToggleDisplay)>();
Expand Down
177 changes: 177 additions & 0 deletions src/screen/playing/victory_menu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
use bevy::prelude::*;
use bevy_kira_audio::prelude::*;
use bevy_mod_picking::prelude::*;
use pyri_state::extra::entity_scope::StateScope;
use pyri_state::prelude::*;

use crate::core::pause::Pause;
use crate::core::UpdateSet;
use crate::game::actor::level::up::LevelUp;
use crate::game::actor::level::Level;
use crate::screen::fade_out;
use crate::screen::playing::PlayingAssets;
use crate::screen::playing::PlayingMenu;
use crate::screen::Screen;
use crate::ui::prelude::*;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.add_systems(
StateFlush,
PlayingMenu::Victory.on_edge(Pause::disable, (Pause::enable_default, open_victory_menu)),
);

app.init_resource::<EndlessMode>();

app.add_systems(
Update,
PlayingMenu::Victory
.enter()
.in_set(UpdateSet::SyncLate)
.run_if(on_event::<LevelUp>().and_then(detect_victory)),
);
}

#[derive(Default, Resource)]
pub struct EndlessMode(bool);

fn open_victory_menu(mut commands: Commands, ui_root: Res<UiRoot>) {
commands
.spawn_with(victory_overlay)
.set_parent(ui_root.body);
commands.spawn_with(victory_menu).set_parent(ui_root.body);
}

pub fn detect_victory(level_query: Query<&Level>, endless_mode: Res<EndlessMode>) -> bool {
if endless_mode.0 {
return false;
}

if let Some(level) = level_query.iter().last() {
return level.current >= 10;
}

false
}

fn victory_overlay(mut entity: EntityWorldMut) {
entity.add(widget::blocking_overlay).insert((
Name::new("VictoryOverlay"),
ZIndex::Global(1),
ThemeColor::Overlay.target::<BackgroundColor>(),
StateScope::<PlayingMenu>::default(),
));
}

fn victory_menu(mut entity: EntityWorldMut) {
entity
.insert((
Name::new("VictoryMenu"),
NodeBundle {
style: Style::ABS_COLUMN_MID,
z_index: ZIndex::Global(2),
..default()
},
StateScope::<PlayingMenu>::default(),
))
.with_children(|children| {
children.spawn_with(header);
children.spawn_with(button_container);
});
}

const HEADER: &str = "Victory :)";

fn header(mut entity: EntityWorldMut) {
entity.insert((
Name::new("Header"),
TextBundle::from_section(
HEADER,
TextStyle {
font: BOLD_FONT_HANDLE,
..default()
},
)
.with_style(Style {
margin: UiRect::top(Vw(4.5)),
..default()
}),
DynamicFontSize::new(Vw(5.0)).with_step(8.0),
ThemeColorForText(vec![ThemeColor::BodyText]),
));
}

fn button_container(mut entity: EntityWorldMut) {
entity
.insert((
Name::new("ButtonContainer"),
NodeBundle {
style: Style {
align_items: AlignItems::Center,
flex_direction: FlexDirection::Column,
margin: UiRect::top(VMin(6.0)),
row_gap: Vw(2.5),
..default()
},
..default()
},
))
.with_children(|children| {
children.spawn_with(keep_playing_button);
children.spawn_with(restart_button);
children.spawn_with(quit_to_title_button);
});
}

pub fn reset_endless_mode(mut endless_mode: ResMut<EndlessMode>) {
endless_mode.0 = false;
}

fn keep_playing_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Keep Playing")).insert((
On::<Pointer<Click>>::run(
|mut endless_mode: ResMut<EndlessMode>, mut playing_menu: NextMut<PlayingMenu>| {
endless_mode.0 = true;
playing_menu.disable();
},
),
Style {
height: Vw(9.0),
width: Vw(38.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
));
}

fn restart_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Restart")).insert((
On::<Pointer<Click>>::run(
|mut commands: Commands, audio: Res<Audio>, assets: Res<PlayingAssets>| {
audio.play(assets.sfx_restart.clone()).with_volume(0.7);
commands.spawn_with(fade_out(Screen::Playing));
},
),
Style {
height: Vw(9.0),
width: Vw(38.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
));
}

fn quit_to_title_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Quit to title")).insert((
On::<Pointer<Click>>::run(Screen::Title.enter()),
Style {
height: Vw(9.0),
width: Vw(38.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
));
}

0 comments on commit cd5cc93

Please sign in to comment.