use winit::{ dpi::PhysicalPosition, event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode}, }; #[derive(Debug)] pub struct InputStatus { // Parameters scroll_speed: f32, mouse_position: PhysicalPosition, // Continuous keys key_left: bool, key_right: bool, key_thrust: bool, key_guns: bool, key_leftclick: bool, // One-shot keys (automatically released at the end of each frame) key_land: bool, v_scroll: f32, } impl InputStatus { pub fn new() -> Self { InputStatus { key_left: false, key_right: false, key_thrust: false, key_guns: false, key_land: false, key_leftclick: false, mouse_position: PhysicalPosition { x: 0.0, y: 0.0 }, v_scroll: 0.0, scroll_speed: 10.0, } } pub fn release_all(&mut self) { self.key_left = false; self.key_right = false; self.key_thrust = false; self.key_guns = false; self.key_land = false; } /// Called at the end of every frame, /// resets one-shot keys. pub fn clear_inputs(&mut self) { self.key_land = false; self.v_scroll = 0.0; } pub fn process_key(&mut self, state: &ElementState, key: &VirtualKeyCode) { let down = state == &ElementState::Pressed; match key { VirtualKeyCode::Left => { self.key_left = down; if down { self.key_right = false; } } VirtualKeyCode::Right => { self.key_right = down; if down { self.key_left = false; } } VirtualKeyCode::Up => self.key_thrust = down, VirtualKeyCode::Space => self.key_guns = down, VirtualKeyCode::L => self.key_land = down, _ => {} } } pub fn process_mouse(&mut self, position: &PhysicalPosition) { self.mouse_position = PhysicalPosition { x: position.x as f32, y: position.y as f32, }; } pub fn process_click(&mut self, state: &ElementState, key: &MouseButton) { let down = state == &ElementState::Pressed; match key { MouseButton::Left => self.key_leftclick = down, _ => {} } } pub fn process_scroll(&mut self, delta: &MouseScrollDelta, _phase: &TouchPhase) { match delta { MouseScrollDelta::LineDelta(_h, v) => { self.v_scroll -= self.scroll_speed * v; } // TODO: handle this better MouseScrollDelta::PixelDelta(v) => { self.v_scroll -= v.x as f32; } } } } // Public get-state methods impl InputStatus { /// Has the player applied vertical scroll? /// This is measured in lines, scaled by scroll_speed /// /// A positive value means scroll up, a negative value means scroll down. /// This is reset to zero at the end of each frame. pub fn get_v_scroll(&self) -> f32 { self.v_scroll } /// Get the current mouse position pub fn get_mouse_pos(&self) -> PhysicalPosition { self.mouse_position } /// Is the player pressing the "turn left" key? pub fn pressed_left(&self) -> bool { self.key_left } /// Is the player pressing the "turn right" key? pub fn pressed_right(&self) -> bool { self.key_right } /// Is the player pressing the "fowards" key? pub fn pressed_thrust(&self) -> bool { self.key_thrust } /// Is the player pressing the "fire guns" key? pub fn pressed_guns(&self) -> bool { self.key_guns } /// Is the player pressing the left mouse button? pub fn pressed_leftclick(&self) -> bool { self.key_leftclick } /// Has the player pressed the "land" key? /// (One-shot, reset to false at the start of each frame) pub fn pressed_land(&self) -> bool { self.key_land } }