diff --git a/src/game.rs b/src/game.rs index 93c19b19..c2d0ef07 100644 --- a/src/game.rs +++ b/src/game.rs @@ -116,6 +116,9 @@ impl geng::State for Game { geng::Event::CursorMove { position } => { self.ui_context.cursor.cursor_move(position.as_f32()); } + geng::Event::MousePress { + button: geng::MouseButton::Left, + } => self.model.cursor_clicked = true, geng::Event::TouchStart(touch) if self.active_touch.is_none() => { self.active_touch = Some(touch.id); } @@ -197,5 +200,6 @@ impl geng::State for Game { .screen_to_world(game_pos.size(), pos) .as_r32(); self.model.update(target_pos, delta_time); + self.model.cursor_clicked = false; } } diff --git a/src/menu/level.rs b/src/menu/level.rs index 3dc0ad1f..8314ff01 100644 --- a/src/menu/level.rs +++ b/src/menu/level.rs @@ -653,6 +653,9 @@ impl geng::State for LevelMenu { .play_button .base_collider .contains(cursor_world.as_r32()); + if hovering && self.ui_context.cursor.was_down { + self.play_button.clicked = true; + } self.play_button.update(hovering, delta_time); } if self.play_button.hover_time.is_max() { diff --git a/src/menu/main.rs b/src/menu/main.rs index d6a2c3a2..17ce8e4c 100644 --- a/src/menu/main.rs +++ b/src/menu/main.rs @@ -15,6 +15,8 @@ pub struct MainMenu { framebuffer_size: vec2, /// Cursor position in screen space. cursor_pos: vec2, + /// Cursor clicked last frame. + clicked: bool, active_touch: Option, cursor_world_pos: vec2, camera: Camera2d, @@ -39,6 +41,7 @@ impl MainMenu { cursor_pos: vec2::ZERO, active_touch: None, cursor_world_pos: vec2::ZERO, + clicked: false, camera: Camera2d { center: vec2::ZERO, rotation: Angle::ZERO, @@ -97,6 +100,9 @@ impl geng::State for MainMenu { self.player.reset_distance(); let hovering = self.player.collider.check(&self.play_button.base_collider); + if hovering && self.clicked { + self.play_button.clicked = true; + } self.play_button.update(hovering, delta_time); self.player .update_distance_simple(&self.play_button.base_collider); @@ -104,6 +110,8 @@ impl geng::State for MainMenu { self.play_button.hover_time.set_ratio(Time::ZERO); self.play(); } + + self.clicked = false; } fn fixed_update(&mut self, delta_time: f64) { @@ -116,6 +124,9 @@ impl geng::State for MainMenu { geng::Event::CursorMove { position } => { self.cursor_pos = position; } + geng::Event::MousePress { + button: geng::MouseButton::Left, + } => self.clicked = true, geng::Event::TouchStart(touch) if self.active_touch.is_none() => { self.active_touch = Some(touch.id); } diff --git a/src/model/logic/mod.rs b/src/model/logic/mod.rs index 4af62b62..a74ba348 100644 --- a/src/model/logic/mod.rs +++ b/src/model/logic/mod.rs @@ -150,6 +150,9 @@ impl Model { .restart_button .base_collider .check(&self.player.collider); + if hovering && self.cursor_clicked { + self.restart_button.clicked = true; + } self.restart_button.update(hovering, delta_time); self.player .update_distance_simple(&self.restart_button.base_collider); @@ -159,6 +162,9 @@ impl Model { // 1 second before the UI is active let hovering = self.exit_button.base_collider.check(&self.player.collider); + if hovering && self.cursor_clicked { + self.exit_button.clicked = true; + } self.exit_button.update(hovering, delta_time); self.player .update_distance_simple(&self.exit_button.base_collider); diff --git a/src/model/mod.rs b/src/model/mod.rs index ae9118c2..57a571f8 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -23,6 +23,7 @@ pub struct HoverButton { pub base_collider: Collider, pub hover_time: Lifetime, pub animation: Movement, + pub clicked: bool, } impl HoverButton { @@ -36,21 +37,29 @@ impl HoverButton { key_frames: vec![MoveFrame::scale(0.5, 5.0), MoveFrame::scale(0.25, 75.0)].into(), fade_out: r32(0.2), }, + clicked: false, } } /// Whether is button is now fading, i.e. going to finish its animation regardless of input. pub fn is_fading(&self) -> bool { // TODO: more custom - self.hover_time.get_ratio().as_f32() > 0.5 + self.hover_time.get_ratio().as_f32() > 0.6 } pub fn update(&mut self, hovering: bool, delta_time: Time) { - self.hover_time.change(if self.is_fading() || hovering { - delta_time + let scale = if self.is_fading() { + self.clicked = false; + 1.0 + } else if self.clicked { + 3.0 + } else if hovering { + 1.0 } else { - -delta_time - }); + -1.0 + }; + let dt = r32(scale) * delta_time; + self.hover_time.change(dt); } } @@ -94,6 +103,8 @@ pub struct Model { pub high_score: i32, pub camera: Camera2d, pub player: Player, + /// Whether the cursor clicked last frame. + pub cursor_clicked: bool, pub options: Options, /// The level being played. Not changed, apart from music being played. @@ -163,6 +174,7 @@ impl Model { ), level.config.health.max, ), + cursor_clicked: false, level_state: LevelState::default(), state: State::Starting {