fix(input): restore launcher press and release impulses
The rewrite used a 375-millipixel impulse for both charging and release. The reconstructed key handlers use the setup scalar 15: every repeated Down keydown subtracts 15*50, and release subtracts a further 15*100 before clamping. Use 750-millipixel press increments and the 1,500-millipixel release impulse, then reproduce the randomized -3800 lower clamp and weak -2280 upper branch. Derive the ten launcher decoration frames from the original strict multiples of 750 and keep integration/gravity assertions separate from the immediate release state. Test Plan: - `cargo test --all-targets` -- passed, 60 tests - `cargo clippy --all-targets -- -D warnings` -- passed - `rumdl check tdkpin-rs/CHANGELOG.md tdkpin-rs/RECONSTRUCTION.md` -- passed - `git diff --cached --check` -- passed
This commit is contained in:
+36
-12
@@ -20,9 +20,8 @@ const RIGHT_FLIPPER_PIVOT: Vec2 = Vec2::new(210.0, 397.0);
|
||||
const RIGHT_FLIPPER_REST_TIP: Vec2 = Vec2::new(179.0, 419.0);
|
||||
const RIGHT_FLIPPER_RAISED_TIP: Vec2 = Vec2::new(181.0, 376.0);
|
||||
const LAUNCHER_POSITION: Vec2 = Vec2::new(325.0, 413.0);
|
||||
const LAUNCHER_FRAME_THRESHOLDS: [f32; 10] =
|
||||
[0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95];
|
||||
const LAUNCHER_IMPULSE_MILLI: i32 = 375;
|
||||
const LAUNCHER_PRESS_IMPULSE_MILLI: i32 = 750;
|
||||
const LAUNCHER_RELEASE_IMPULSE_MILLI: i32 = 1_500;
|
||||
const LAUNCHER_REPEAT_DELAY_SECONDS: f32 = 0.650;
|
||||
const LAUNCHER_REPEAT_SECONDS: f32 = 0.040;
|
||||
const CLAW_TRIGGER_CENTER: Vec2 = Vec2::new(289.0, 94.0);
|
||||
@@ -333,7 +332,15 @@ impl Game {
|
||||
}
|
||||
|
||||
pub fn launcher_frame(&self) -> usize {
|
||||
LAUNCHER_FRAME_THRESHOLDS.partition_point(|threshold| self.launcher_charge >= *threshold)
|
||||
if !self.launcher_was_down {
|
||||
return 0;
|
||||
}
|
||||
(1..=10)
|
||||
.find(|multiple| {
|
||||
-LAUNCHER_PRESS_IMPULSE_MILLI * i32::try_from(*multiple).unwrap_or(10)
|
||||
< self.launcher_velocity_milli
|
||||
})
|
||||
.unwrap_or(10)
|
||||
}
|
||||
|
||||
pub fn add_player_before_launch(&mut self) -> bool {
|
||||
@@ -354,11 +361,15 @@ impl Game {
|
||||
}
|
||||
|
||||
fn fire_launcher(&mut self) {
|
||||
self.launcher_velocity_milli -= LAUNCHER_IMPULSE_MILLI;
|
||||
self.launcher_velocity_milli = self
|
||||
.launcher_velocity_milli
|
||||
.wrapping_sub(LAUNCHER_RELEASE_IMPULSE_MILLI);
|
||||
let mut launch_velocity = self.launcher_velocity_milli;
|
||||
if launch_velocity < -MAXIMUM_SPEED_MILLI_PER_STEP {
|
||||
let variation = self.random.below(3_800) / 40;
|
||||
launch_velocity = -MAXIMUM_SPEED_MILLI_PER_STEP + i32::from(variation);
|
||||
} else if launch_velocity > -2_280 {
|
||||
launch_velocity = launch_velocity.wrapping_sub(i32::from(self.random.below(3_800) / 40));
|
||||
}
|
||||
self.ball.in_launcher = false;
|
||||
self.ball.velocity = MilliVec {
|
||||
@@ -401,11 +412,15 @@ impl Game {
|
||||
if self.launcher_was_down {
|
||||
self.launcher_hold_seconds += frame_time.min(0.05);
|
||||
while self.launcher_hold_seconds >= self.launcher_next_repeat {
|
||||
self.launcher_velocity_milli -= LAUNCHER_IMPULSE_MILLI;
|
||||
self.launcher_velocity_milli = self
|
||||
.launcher_velocity_milli
|
||||
.wrapping_sub(LAUNCHER_PRESS_IMPULSE_MILLI);
|
||||
self.launcher_next_repeat += LAUNCHER_REPEAT_SECONDS;
|
||||
}
|
||||
} else {
|
||||
self.launcher_velocity_milli -= LAUNCHER_IMPULSE_MILLI;
|
||||
self.launcher_velocity_milli = self
|
||||
.launcher_velocity_milli
|
||||
.wrapping_sub(LAUNCHER_PRESS_IMPULSE_MILLI);
|
||||
self.launcher_was_down = true;
|
||||
}
|
||||
let charge_milli =
|
||||
@@ -1392,11 +1407,20 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn holding_the_launcher_produces_a_faster_shot() {
|
||||
let mut quick = Game::new(1);
|
||||
launch_ball(&mut quick, 1);
|
||||
let mut quick = Game::new_with_seed(1, 7);
|
||||
let held = Controls {
|
||||
launch_down: true,
|
||||
..Controls::default()
|
||||
};
|
||||
quick.update(0.0, 3, held);
|
||||
quick.update(0.0, 3, Controls::default());
|
||||
let quick_speed = -quick.ball.velocity.y;
|
||||
assert_eq!(
|
||||
MilliVec::from_velocity_per_second(quick.ball.velocity),
|
||||
MilliVec { x: 0, y: -2_270 }
|
||||
);
|
||||
|
||||
let mut charged = Game::new(1);
|
||||
let mut charged = Game::new_with_seed(1, 7);
|
||||
launch_ball(&mut charged, 60);
|
||||
let charged_speed = -charged.ball.velocity.y;
|
||||
|
||||
@@ -1414,8 +1438,8 @@ mod tests {
|
||||
for _ in 0..30 {
|
||||
game.update(1.0 / 60.0, 3, held);
|
||||
}
|
||||
assert!((0.09..0.11).contains(&game.launcher_charge));
|
||||
assert_eq!(game.launcher_frame(), 1);
|
||||
assert!((0.19..0.21).contains(&game.launcher_charge));
|
||||
assert_eq!(game.launcher_frame(), 2);
|
||||
|
||||
for _ in 0..30 {
|
||||
game.update(1.0 / 60.0, 3, held);
|
||||
|
||||
@@ -409,7 +409,7 @@ mod tests {
|
||||
let mut simulation = Simulation::new(Scenario::Launcher, 1);
|
||||
simulation.advance_to(60);
|
||||
assert!(simulation.game.ball.in_launcher);
|
||||
assert!((0.09..=0.11).contains(&simulation.game.launcher_charge));
|
||||
assert!((0.19..=0.21).contains(&simulation.game.launcher_charge));
|
||||
|
||||
simulation.advance_to(121);
|
||||
assert!(!simulation.game.ball.in_launcher);
|
||||
|
||||
Reference in New Issue
Block a user