From 1dfe56ac50f6a089ed9e3fb188184269bb15ef63 Mon Sep 17 00:00:00 2001 From: cool-mist Date: Sun, 11 May 2025 19:00:52 +0530 Subject: [PATCH] Animation on button click --- src/game.rs | 3 +- src/game/button.rs | 113 ++++++++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/game.rs b/src/game.rs index 4aedf35..f8a14d1 100644 --- a/src/game.rs +++ b/src/game.rs @@ -100,7 +100,7 @@ impl Game { let mut button_action = None; for btn in &mut self.btns { btn.handle_input(); - if btn.is_pressed { + if btn.is_clicked() { button_action = Some(btn.action); } } @@ -431,7 +431,6 @@ impl Game { self.board = self.original_board.clone(); self.reset_squares(); for btn in &mut self.btns { - btn.reset(); if let ButtonAction::Next = btn.action { btn.is_active = false; } diff --git a/src/game/button.rs b/src/game/button.rs index e7c72c0..42bc136 100644 --- a/src/game/button.rs +++ b/src/game/button.rs @@ -2,10 +2,12 @@ use macroquad::prelude::*; pub struct Button { pub text: String, - pub is_pressed: bool, pub is_active: bool, pub action: ButtonAction, + is_down: bool, + is_clicked: bool, rect: Rect, + shadow_width: f32, } #[derive(Debug, Clone, Copy)] @@ -19,13 +21,24 @@ impl Button { let rect = Rect::new(x, y, width, height); Self { text: text.to_string(), - is_pressed: false, + is_down: false, + is_clicked: false, is_active: true, rect, action, + shadow_width: 5.0, } } + pub fn is_clicked(&mut self) -> bool { + if self.is_clicked { + self.is_clicked = false; + return true; + } + + false + } + pub fn draw(&self) { self.draw_button(); self.draw_label(); @@ -33,81 +46,119 @@ impl Button { fn draw_button(&self) { let bg_color = Color::from_rgba(190, 190, 190, 255); - draw_rectangle(self.rect.x, self.rect.y, self.rect.w, self.rect.h, bg_color); + let button_draw_offset = self.get_button_draw_offset(); + draw_rectangle( + self.rect.x + button_draw_offset, + self.rect.y + button_draw_offset, + self.rect.w, + self.rect.h, + bg_color, + ); + + self.draw_shadow(); + } + + fn draw_shadow(&self) { + if !self.is_active { + return; + } + + if self.is_down { + return; + } let color = Color::from_rgba(0, 0, 0, 100); - let width = 5.0; draw_rectangle( self.rect.x + self.rect.w, - self.rect.y + width, - width, + self.rect.y + self.shadow_width, + self.shadow_width, self.rect.h, color, ); draw_rectangle( - self.rect.x + width, + self.rect.x + self.shadow_width, self.rect.y + self.rect.h, - self.rect.w - width, - width, + self.rect.w - self.shadow_width, + self.shadow_width, color, ); draw_triangle( vec2(self.rect.x + self.rect.w, self.rect.y), - vec2(self.rect.x + self.rect.w + width, self.rect.y + width), - vec2(self.rect.x + self.rect.w, self.rect.y + width), + vec2( + self.rect.x + self.rect.w + self.shadow_width, + self.rect.y + self.shadow_width, + ), + vec2(self.rect.x + self.rect.w, self.rect.y + self.shadow_width), color, ); draw_triangle( vec2(self.rect.x, self.rect.y + self.rect.h), - vec2(self.rect.x + width, self.rect.y + self.rect.h + width), - vec2(self.rect.x + width, self.rect.y + self.rect.h), + vec2( + self.rect.x + self.shadow_width, + self.rect.y + self.rect.h + self.shadow_width, + ), + vec2(self.rect.x + self.shadow_width, self.rect.y + self.rect.h), color, ); } fn draw_label(&self) { - let font_color = if self.is_active { - Color::from_rgba(0, 0, 0, 255) - } else { - Color::from_rgba(100, 0, 0, 255) + let font_color = match self.is_active { + true => Color::from_rgba(0, 0, 0, 255), + false => Color::from_rgba(100, 100, 100, 255) }; let font_size = (0.5 * self.rect.h) as u16; let dims = measure_text(&self.text, None, font_size, 1.0); + let button_draw_offset = self.get_button_draw_offset(); + draw_text( &self.text, - self.rect.x + (self.rect.w - dims.width) * 0.5, - self.rect.y + (self.rect.h - dims.height) * 0.5 + dims.offset_y, + self.rect.x + (self.rect.w - dims.width) * 0.5 + button_draw_offset, + self.rect.y + (self.rect.h - dims.height) * 0.5 + dims.offset_y + button_draw_offset, font_size as f32, font_color, ); } - pub fn reset(&mut self) { - self.is_pressed = false; - self.is_active = true; + fn get_button_draw_offset(&self) -> f32 { + let button_pressed_correction = match self.is_down { + true => self.shadow_width, + false => match self.is_active { + true => 0.0, + false => self.shadow_width, + }, + }; + button_pressed_correction } pub fn handle_input(&mut self) { if !self.is_active { - return; - } - - if !is_mouse_button_released(MouseButton::Left) { - self.is_pressed = false; + self.is_down = false; return; } let (mx, my) = mouse_position(); let c = Circle::new(mx, my, 0.0); - if c.overlaps_rect(&self.rect) { - self.is_pressed = true; - return; + + if is_mouse_button_pressed(MouseButton::Left) { + if c.overlaps_rect(&self.rect) { + self.is_down = true; + return; + } } - self.is_pressed = false; + if is_mouse_button_released(MouseButton::Left) { + if c.overlaps_rect(&self.rect) { + self.is_clicked = true; + self.is_down = false; + return; + } + + self.is_down = false; + } } }