Skip to content

Commit d28a07b

Browse files
committed
add a proper game over screen
closes #50 closes #49
1 parent e02f1ea commit d28a07b

File tree

6 files changed

+196
-24
lines changed

6 files changed

+196
-24
lines changed

art/fonts.aseprite

1.39 KB
Binary file not shown.

assets/font.ttf

7.4 KB
Binary file not shown.

src/main.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use bevy::{
1010

1111
use bevy_embedded_assets::{EmbeddedAssetPlugin, PluginMode};
1212

13-
use crate::input::InputPlugin;
13+
use crate::{input::InputPlugin, sundry::BLACK};
1414

1515
mod audio;
1616
mod input;
@@ -123,10 +123,11 @@ fn spawn_camera(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
123123
Camera {
124124
order: -1,
125125
target: RenderTarget::Image(image_handle.clone().into()),
126-
clear_color: ClearColorConfig::Custom(Color::srgb_u8(9, 10, 20)),
126+
clear_color: ClearColorConfig::Custom(BLACK),
127127
..default()
128128
},
129129
Msaa::Off,
130+
UiAntiAlias::Off,
130131
InGameCamera,
131132
PIXEL_PERFECT_LAYERS,
132133
));

src/screens/game.rs

Lines changed: 188 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
use bevy::prelude::*;
1+
use bevy::{prelude::*, text::FontSmoothing};
22
use leafwing_input_manager::prelude::*;
33
use rand::random_range;
44

55
use crate::{
6-
PIXEL_PERFECT_LAYERS,
6+
PIXEL_PERFECT_LAYERS, ScaleFactor,
77
audio::{PlaySfxEvent, PlaySoundtrackEvent, SoundEffect, Soundtrack},
88
input::Action,
99
screens::Screen,
10+
sundry::BLACK,
1011
};
1112

12-
// #[derive(Resource)]
13-
// pub struct GameStats {
14-
// pub asteroids_destroyed: u32,
15-
// pub distance_traveled: u32,
16-
// pub shots_fired: u32,
17-
// pub shots_hit: u32,
18-
// pub time_played: f32,
19-
// }
13+
#[derive(Resource)]
14+
pub struct GameStats {
15+
pub asteroids_destroyed: u32,
16+
pub distance_traveled: u32,
17+
pub shots_fired: u32,
18+
pub shots_hit: u32,
19+
// pub time_played: f32,
20+
// pub successful_trip: bool,
21+
}
2022

2123
#[derive(States, Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
2224
pub enum GameState {
@@ -33,6 +35,14 @@ struct HasEntered(bool);
3335

3436
pub(super) fn plugin(app: &mut App) {
3537
app.init_state::<GameState>();
38+
app.insert_resource(GameStats {
39+
asteroids_destroyed: 0,
40+
distance_traveled: 0,
41+
shots_fired: 0,
42+
shots_hit: 0,
43+
// time_played: 0.0,
44+
// successful_trip: false,
45+
});
3646
app.insert_resource::<HasEntered>(HasEntered(false));
3747

3848
app.add_systems(
@@ -146,7 +156,12 @@ fn enter_player(
146156
mut player: Query<(&mut Transform, &ShipSpeedSprites), With<Player>>,
147157
mut thruster: Query<&mut Sprite, With<Thruster>>,
148158
mut has_entered: ResMut<HasEntered>,
159+
mut game_stats: ResMut<GameStats>,
149160
) {
161+
game_stats.asteroids_destroyed = 0;
162+
game_stats.distance_traveled = 0;
163+
game_stats.shots_fired = 0;
164+
game_stats.shots_hit = 0;
150165
let player = player.single_mut();
151166
if player.is_err() {
152167
return;
@@ -223,6 +238,7 @@ fn player_input(
223238
mut thruster: Query<&mut Sprite, With<Thruster>>,
224239
time: Res<Time<Virtual>>,
225240
asset_server: Res<AssetServer>,
241+
mut game_stats: ResMut<GameStats>,
226242
) {
227243
let action_state = input_query.single().unwrap();
228244
let player = player_query.single_mut();
@@ -274,6 +290,9 @@ fn player_input(
274290
}
275291

276292
if action_state.pressed(&Action::Shoot) && player.can_shoot {
293+
player.can_shoot = false;
294+
player.timer.reset();
295+
game_stats.shots_fired += 1;
277296
commands.trigger(PlaySfxEvent {
278297
sfx: SoundEffect::Shoot,
279298
});
@@ -291,8 +310,6 @@ fn player_input(
291310
Projectile,
292311
DespawnOnExit(Screen::Game),
293312
));
294-
player.can_shoot = false;
295-
player.timer.reset();
296313
}
297314
}
298315

@@ -446,15 +463,18 @@ fn projectile_asteroid_collision(
446463
projectiles: Query<(Entity, &Transform), With<Projectile>>,
447464
mut asteroids: Query<(Entity, &Transform, &mut Asteroid)>,
448465
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
466+
mut game_stats: ResMut<GameStats>,
449467
) {
450468
for (projectile_entity, projectile_transform) in projectiles.iter() {
451469
for (asteroid_entity, asteroid_transform, mut asteroid) in asteroids.iter_mut() {
452470
let distance = projectile_transform
453471
.translation
454472
.distance(asteroid_transform.translation);
455473
if distance < (16.0 / 2.0) + (30.0 / 2.0) {
474+
game_stats.shots_hit += 1;
456475
asteroid.health -= 1;
457476
if asteroid.health == 0 {
477+
game_stats.asteroids_destroyed += 1;
458478
commands.entity(asteroid_entity).despawn();
459479
}
460480
commands.entity(projectile_entity).despawn();
@@ -498,33 +518,128 @@ fn update_explosions(
498518
}
499519
}
500520

501-
fn spawn_game_over(mut commands: Commands) {
521+
fn spawn_game_over(
522+
mut commands: Commands,
523+
asset_server: Res<AssetServer>,
524+
scale_factor: Res<ScaleFactor>,
525+
game_stats: Res<GameStats>,
526+
) {
527+
let scale = scale_factor.0;
528+
let font_handle: Handle<Font> = asset_server.load("font.ttf");
529+
502530
commands.spawn((
503531
Name::new("Game Over Screen"),
504532
Transform {
505533
translation: Vec3::new(0.0, 0.0, 100.0),
506534
..default()
507535
},
508-
Node::default(),
536+
Node {
537+
width: Val::Percent(70.0),
538+
height: Val::Percent(70.0),
539+
position_type: PositionType::Absolute,
540+
justify_content: JustifyContent::Center,
541+
margin: UiRect::all(Val::Auto),
542+
..default()
543+
},
509544
DespawnOnExit(Screen::Game),
510545
DespawnOnExit(GameState::GameOver),
511546
PIXEL_PERFECT_LAYERS,
512547
children![
513548
(
514549
Name::new("Game Over Text"),
515-
Text::new("Game Over"),
516-
Node::default()
550+
Text::new("GAME OVER"),
551+
TextFont {
552+
font_size: 16.0 * scale,
553+
font: font_handle.clone(),
554+
font_smoothing: FontSmoothing::None,
555+
556+
..default()
557+
},
558+
Node {
559+
position_type: PositionType::Absolute,
560+
top: Val::Px(8.0 * scale),
561+
margin: UiRect {
562+
left: Val::Auto,
563+
right: Val::Auto,
564+
..default()
565+
},
566+
..default()
567+
}
568+
),
569+
(
570+
Name::new("Stats container"),
571+
Node {
572+
display: Display::Flex,
573+
flex_direction: FlexDirection::Column,
574+
..default()
575+
},
576+
children![
577+
stats_row(
578+
"DISTANCE TRAVELED",
579+
&game_stats.distance_traveled.to_string(),
580+
scale,
581+
font_handle.clone(),
582+
),
583+
stats_row(
584+
"SHOTS FIRED",
585+
&game_stats.shots_fired.to_string(),
586+
scale,
587+
font_handle.clone(),
588+
),
589+
stats_row(
590+
"SHOTS HIT",
591+
&game_stats.shots_hit.to_string(),
592+
scale,
593+
font_handle.clone()
594+
),
595+
stats_row(
596+
"ASTEROIDS DESTROYED",
597+
&game_stats.asteroids_destroyed.to_string(),
598+
scale,
599+
font_handle.clone(),
600+
),
601+
]
517602
),
518603
(
519604
Name::new("Replay Button"),
520605
Button,
521606
Node {
522-
margin: UiRect::all(Val::Px(10.0)),
523-
padding: UiRect::all(Val::Px(10.0)),
607+
position_type: PositionType::Absolute,
608+
bottom: Val::Px(32.0 * scale),
524609
..default()
525610
},
526-
BackgroundColor(Color::BLACK),
527-
children![(Name::new("Replay Button Text"), Text::new("Replay"))],
611+
children![(
612+
Name::new("Replay Button Text"),
613+
Text::new("REPLAY"),
614+
Node::default(),
615+
TextFont {
616+
font_size: 16.0 * scale,
617+
font: font_handle.clone(),
618+
font_smoothing: FontSmoothing::None,
619+
..default()
620+
}
621+
)],
622+
),
623+
(
624+
Name::new("Back to Menu Button"),
625+
Button,
626+
Node {
627+
position_type: PositionType::Absolute,
628+
bottom: Val::Px(8.0 * scale),
629+
..default()
630+
},
631+
children![(
632+
Name::new("Back to Menu Text"),
633+
Text::new("BACK TO MENU"),
634+
Node::default(),
635+
TextFont {
636+
font_size: 16.0 * scale,
637+
font: font_handle.clone(),
638+
font_smoothing: FontSmoothing::None,
639+
640+
..default()
641+
}
642+
)]
528643
)
529644
],
530645
));
@@ -567,3 +682,56 @@ fn trigger_music(mut commands: Commands) {
567682
soundtrack: Soundtrack::BattleTheme,
568683
});
569684
}
685+
686+
fn stats_row(stat: &str, value: &str, scale: f32, font_handle: Handle<Font>) -> impl Bundle {
687+
(
688+
Name::new(format!("{stat} Stat")),
689+
BackgroundColor(BLACK),
690+
Node {
691+
display: Display::Flex,
692+
justify_content: JustifyContent::SpaceBetween,
693+
top: Val::Px(32.0 * scale),
694+
width: Val::Percent(100.0),
695+
padding: UiRect {
696+
top: Val::Px(8.0 * scale),
697+
..default()
698+
},
699+
margin: UiRect {
700+
left: Val::Px(32.0 * scale),
701+
right: Val::Px(32.0 * scale),
702+
..default()
703+
},
704+
..default()
705+
},
706+
children![
707+
(
708+
Name::new(format!("{stat} Label")),
709+
Text::new(stat),
710+
TextFont {
711+
font_size: 16.0 * scale,
712+
font: font_handle.clone(),
713+
font_smoothing: FontSmoothing::None,
714+
..default()
715+
},
716+
Node {
717+
left: Val::Px(0.0),
718+
..default()
719+
},
720+
),
721+
(
722+
Name::new(format!("{stat} Value")),
723+
Text::new(value),
724+
TextFont {
725+
font_size: 16.0 * scale,
726+
font: font_handle.clone(),
727+
font_smoothing: FontSmoothing::None,
728+
..default()
729+
},
730+
Node {
731+
right: Val::Px(0.0),
732+
..default()
733+
}
734+
)
735+
],
736+
)
737+
}

src/screens/title.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy::prelude::*;
1+
use bevy::{prelude::*, text::FontSmoothing};
22
use leafwing_input_manager::prelude::ActionState;
33

44
use crate::{
@@ -58,11 +58,12 @@ fn spawn_title_screen(
5858
font_handle.clone(),
5959
scale,
6060
);
61-
let quit = title_menu_button("QUIT", 2, MenuButton::Quit, font_handle.clone(), scale);
6261

6362
#[cfg(target_arch = "wasm32")]
6463
let menu_buttons = children![new_game, settings];
6564
#[cfg(not(target_arch = "wasm32"))]
65+
let quit = title_menu_button("QUIT", 2, MenuButton::Quit, font_handle.clone(), scale);
66+
#[cfg(not(target_arch = "wasm32"))]
6667
let menu_buttons = children![new_game, settings, quit];
6768

6869
commands.spawn((
@@ -232,6 +233,7 @@ fn title_menu_button(
232233
TextFont {
233234
font_size: 16.0 * scale,
234235
font: font_handle,
236+
font_smoothing: FontSmoothing::None,
235237
..default()
236238
},
237239
FadeIn,

src/sundry.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bevy::prelude::Color;
22

3+
pub const BLACK: Color = Color::srgb_u8(9, 10, 20);
34
pub const WHITE: Color = Color::srgb_u8(235, 237, 233);
45
// pub const TRANSPARENT_WHITE: Color = Color::srgba_u8(235, 237, 233, 0);
56
// pub const LIGHT_GRAY: Color = Color::srgb_u8(199, 207, 204);

0 commit comments

Comments
 (0)