use serde::{Deserialize, Serialize}; use web_time::{SystemTime, UNIX_EPOCH}; use crate::StateTransition; use crate::context::Context; use crate::font::FontSize; use crate::screen::Screen; use macroquad::prelude::*; #[derive(Serialize, Debug)] #[serde(tag = "type")] pub enum PlayerClientMessages { BuzzIn { time: f64 }, } #[derive(Deserialize, Debug)] #[serde(tag = "type")] pub enum PlayerServerMessages { Ack, UpdatePointTotal { score: i32 }, ResetBuzzer, } #[derive(Default)] pub struct PlayerScreen { score: i32, button_pressed: bool, } impl Screen for PlayerScreen { fn handle_messages(&mut self, ctx: &mut Context) -> Option { let msg = ctx.recv_msg(); if let Some(msg) = msg { match msg { PlayerServerMessages::Ack => { info!("Button pressed ack"); self.button_pressed = true; } PlayerServerMessages::ResetBuzzer => { info!("Button press reset"); self.button_pressed = false; } PlayerServerMessages::UpdatePointTotal { score } => { info!("Score updated to: {}", score); self.score = score; } } } None } fn handle_frame(&mut self, ctx: &mut Context) { clear_background(BEIGE); let button_color = if self.button_pressed { Color::from_hex(0xaa0000) } else { RED }; let text_measure = FontSize::Large.measure(&ctx.username); draw_text( &ctx.username, screen_width() * 0.5 - text_measure.width * 0.5, screen_height() * 0.15, FontSize::Large.size() as f32, BLACK, ); let score_text = format!("Score: {}", self.score); let text_measure = FontSize::Large.measure(&score_text); draw_text( &score_text, screen_width() * 0.5 - text_measure.width * 0.5, screen_height() * 0.25, FontSize::Large.size() as f32, BLACK, ); let button_size = (screen_width() * 0.33).min(screen_height() * 0.20); draw_circle( screen_width() * 0.5, screen_height() * 0.5, button_size * 1.1, DARKBROWN, ); draw_circle( screen_width() * 0.5, screen_height() * 0.5, button_size, button_color, ); if !self.button_pressed && is_mouse_button_pressed(MouseButton::Left) { let loc = Vec2::from(mouse_position()); let normalize = loc - Vec2::new(screen_width() * 0.5, screen_height() * 0.5); if normalize.length() < button_size { let timestamp = SystemTime::now(); let unix_timestamp = timestamp.duration_since(UNIX_EPOCH).expect("Time invalid"); let time = unix_timestamp.as_secs_f64(); info!("Button pressed @ {}", time); ctx.send_msg(&PlayerClientMessages::BuzzIn { time }); } } } }