fix(game): launch immediately and enforce tilt

Starting from the attract screen previously created an idle ball and required a
second Down press to launch it. Launch the first ball as part of the start action
while retaining the normal launch action for later balls.

Replace the decaying visual-only tilt value with a latched game state. A tilt now
forfeits the current bonus, suppresses scoring and further nudges, returns both
flippers to rest, and remains active until the ball drains. Keep the warning on
the playfield and use the recovered tilt sound instead of treating the state as
a temporary decorative overlay.

Test Plan:
- `cargo fmt -- --check` -- passed
- `cargo test --all-targets` -- passed, including tilt latch, scoring, flipper,
  drain-reset, and launch coverage
- `cargo clippy --all-targets -- -D warnings` -- passed
- `git diff --check` -- passed
This commit is contained in:
2026-08-22 16:54:12 +02:00
parent e19162d54d
commit 7da0f4d171
2 changed files with 112 additions and 23 deletions
+9 -3
View File
@@ -135,9 +135,14 @@ impl App {
self.assets.play(2012, self.saved.settings.sounds);
}
if is_key_pressed(KeyCode::Down) || is_key_pressed(KeyCode::Enter) {
self.game = Some(Game::new(self.player_count));
let mut game = Game::new(self.player_count);
let launched = game.launch();
self.game = Some(game);
self.screen = Screen::Playing;
self.assets.play(2008, self.saved.settings.sounds);
if launched {
self.assets.play(2016, self.saved.settings.sounds);
}
}
}
@@ -196,6 +201,7 @@ impl App {
Event::Media => 2022,
Event::ExtraBall => 2019,
Event::Nudge | Event::BallSearch => 2021,
Event::Tilt => 2015,
Event::Drain => 2013,
};
self.assets.play(id, self.saved.settings.sounds);
@@ -481,8 +487,8 @@ impl App {
);
self.draw_displays(game);
if game.tilt > 1.15 {
draw_centered("TILT", 263.0, 34, RED);
if game.tilted {
draw_centered_at("TILT", 160.0, 263.0, 30, RED);
}
draw_text("F1 HELP F2 SETUP", 345.0, 448.0, 11.0, BLACK);
}