Skip to content

Commit a8b8859

Browse files
committed
Deal with game over state changes in a uniform way.
1 parent 606b9b1 commit a8b8859

4 files changed

Lines changed: 80 additions & 23 deletions

File tree

src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,6 @@ pub const HEALTH_BAR_DAMP: f32 = 1.0;
104104
pub const TIME_SCALE_DAMP: f32 = 100.0;
105105
pub const GAME_OVER_TIME_SCALE_DAMP: f32 = 5.0;
106106

107+
pub const GAME_OVER_SLOW_MOTION_TIME_SCALE: f32 = 0.2;
107108
pub const GAME_OVER_SLOW_MOTION_DURATION: f32 = 0.8;
108109
pub const GAME_OVER_STATE_CHANGE_DURATION: f32 = 2.0;

src/game/battle.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,34 +60,20 @@ fn enter_battle(
6060
}
6161

6262
/// Deals with [`GameOverEvent`].
63-
/// The system triggers a slow motion with the duration of [`GAME_OVER_SLOW_MOTION_DURATION`]
64-
/// and also changes the [`AppState`] after [`GAME_OVER_STATE_CHANGE_DURATION`].
63+
/// Changes the [`AppState`] after [`GAME_OVER_STATE_CHANGE_DURATION`].
6564
fn game_over_system(
6665
time: Res<Time>,
67-
mut time_scale: ResMut<TimeScale>,
6866
mut app_state: ResMut<State<AppState>>,
6967
mut game_over_events: EventReader<GameOverEvent>,
7068
mut game_over: Local<GameOver>,
7169
) {
7270
if let Some(event) = game_over.event {
73-
let mut target_time_scale = 0.2;
74-
let mut time_scale_damp = TIME_SCALE_DAMP;
75-
76-
if game_over.slow_motion_timer.tick(time.delta()).finished() {
77-
target_time_scale = 1.0;
78-
time_scale_damp = GAME_OVER_TIME_SCALE_DAMP;
79-
}
80-
time_scale.0 = time_scale
81-
.0
82-
.damp(target_time_scale, time_scale_damp, time.delta_seconds());
83-
8471
// it's time to switch state
8572
if game_over
8673
.state_change_timer
8774
.tick(time.delta())
8875
.just_finished()
8976
{
90-
time_scale.reset();
9177
*game_over = GameOver::default();
9278

9379
match event {
@@ -98,7 +84,6 @@ fn game_over_system(
9884
} else {
9985
for event in game_over_events.iter() {
10086
game_over.event = Some(*event);
101-
time_scale.0 = 0.2;
10287
}
10388
}
10489
}

src/game/mod.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl Plugin for GamePlugin {
6060
.with_system(move_slit_block)
6161
.with_system(slits_system)
6262
// effects and juice
63+
.with_system(game_over_slow_motion)
6364
.with_system(bounce_audio)
6465
.with_system(score_audio)
6566
.with_system(score_effects)
@@ -524,12 +525,17 @@ fn reset_ball(
524525
mut commands: Commands,
525526
mut player_miss_events: EventReader<PlayerMissEvent>,
526527
mut player_hit_events: EventReader<PlayerHitEvent>,
528+
mut time_scale: ResMut<TimeScale>,
527529
mut query: Query<(Entity, &mut Transform), (With<Ball>, With<Motion>)>,
528530
) {
529531
let mut closure = |ball| -> Option<()> {
530532
let (_, mut transform) = query.get_mut(ball).ok()?;
531533
transform.translation = Vec3::new(0.0, 0.0, -1.0);
532534
commands.entity(ball).remove::<Motion>();
535+
536+
// also reset time scale
537+
time_scale.reset();
538+
533539
Some(())
534540
};
535541

@@ -716,6 +722,42 @@ fn player_miss(
716722
}
717723
}
718724

725+
/// Deals with [`GameOverEvent`].
726+
/// The system triggers a slow motion with the duration of [`GAME_OVER_SLOW_MOTION_DURATION`]
727+
fn game_over_slow_motion(
728+
time: Res<Time>,
729+
mut time_scale: ResMut<TimeScale>,
730+
mut game_over_events: EventReader<GameOverEvent>,
731+
mut game_over: Local<GameOver>,
732+
) {
733+
if game_over.event.is_some() {
734+
let mut target_time_scale = GAME_OVER_SLOW_MOTION_TIME_SCALE;
735+
let mut time_scale_damp = TIME_SCALE_DAMP;
736+
737+
if game_over.slow_motion_timer.tick(time.delta()).finished() {
738+
target_time_scale = 1.0;
739+
time_scale_damp = GAME_OVER_TIME_SCALE_DAMP;
740+
}
741+
742+
time_scale.0 = time_scale
743+
.0
744+
.damp(target_time_scale, time_scale_damp, time.delta_seconds());
745+
746+
if game_over
747+
.state_change_timer
748+
.tick(time.delta())
749+
.just_finished()
750+
{
751+
time_scale.reset();
752+
*game_over = GameOver::default();
753+
}
754+
} else {
755+
for event in game_over_events.iter() {
756+
game_over.event = Some(*event);
757+
}
758+
}
759+
}
760+
719761
/// Emits [`BounceEvent`] when there the ball hits something after debouncing.
720762
#[allow(clippy::too_many_arguments)]
721763
fn ball_bounce(

src/game/practice.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,28 @@ fn enter_practice(
6868

6969
/// Triggers a full recovery of enemy base health after beating it.
7070
fn recover_enemy_health(
71+
time: Res<Time>,
7172
mut game_over_events: EventReader<GameOverEvent>,
73+
mut game_over: Local<GameOver>,
7274
mut heal_events: EventWriter<HealEvent>,
7375
) {
74-
for event in game_over_events.iter() {
75-
match event {
76-
GameOverEvent::Win => heal_events.send(HealEvent(Heal::default())),
77-
GameOverEvent::Lose => {}
76+
if let Some(event) = game_over.event {
77+
// it's time to switch state
78+
if game_over
79+
.state_change_timer
80+
.tick(time.delta())
81+
.just_finished()
82+
{
83+
*game_over = GameOver::default();
84+
85+
match event {
86+
GameOverEvent::Win => heal_events.send(HealEvent(Heal::default())),
87+
GameOverEvent::Lose => {}
88+
}
89+
}
90+
} else {
91+
for event in game_over_events.iter() {
92+
game_over.event = Some(*event);
7893
}
7994
}
8095
}
@@ -87,11 +102,25 @@ fn player_ball_infinite(mut query: Query<&mut PlayerBase>) {
87102
}
88103

89104
fn progress_system(
105+
time: Res<Time>,
90106
mut practice_state: ResMut<State<PracticeState>>,
91-
game_over_events: EventReader<GameOverEvent>,
107+
mut game_over_events: EventReader<GameOverEvent>,
108+
mut game_over: Local<GameOver>,
92109
) {
93-
if !game_over_events.is_empty() {
94-
let _ = practice_state.set(PracticeState::Slits);
110+
if game_over.event.is_some() {
111+
// it's time to switch state
112+
if game_over
113+
.state_change_timer
114+
.tick(time.delta())
115+
.just_finished()
116+
{
117+
*game_over = GameOver::default();
118+
let _ = practice_state.set(PracticeState::Slits);
119+
}
120+
} else {
121+
for event in game_over_events.iter() {
122+
game_over.event = Some(*event);
123+
}
95124
}
96125
}
97126

0 commit comments

Comments
 (0)