diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 14:33:23 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 14:33:23 -0700 |
| commit | da45c5a7dbb017c8e579d0ab66a2259a70b28f40 (patch) | |
| tree | 938c0be6bd6b938cb8788456ce759b784ee74f5c /src/input.rs | |
| parent | c4c26f03e3eb18a76f9c2756076030dc52a667fa (diff) | |
input manager
Diffstat (limited to 'src/input.rs')
| -rw-r--r-- | src/input.rs | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..dd49cd0 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,159 @@ +use glam::{IVec2, Vec2}; +use winit::{ + event::{KeyEvent, MouseButton, WindowEvent}, + keyboard::{KeyCode, PhysicalKey}, +}; + +use crate::{camera::Camera, sim::cell_manager::manager::CellManager}; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum Input { + // movement + Up, + Left, + Down, + Right, + + // sim management + Pause, + Step, + ClearGrid, + ClearEntities, + ClearParticles, + + // placeholder actions + Action1, + Action2, + Action3, + Action4, + Action5, + Action6, +} + +const INPUT_VAR_LEN: usize = 17; + +const KEYMAP: [(KeyCode, Input); 15] = [ + (KeyCode::KeyW, Input::Up), + (KeyCode::KeyA, Input::Left), + (KeyCode::KeyS, Input::Down), + (KeyCode::KeyD, Input::Right), + (KeyCode::Space, Input::Pause), + (KeyCode::KeyX, Input::Step), + (KeyCode::KeyC, Input::ClearGrid), + (KeyCode::KeyV, Input::ClearEntities), + (KeyCode::KeyP, Input::ClearParticles), + (KeyCode::Digit1, Input::Action1), + (KeyCode::Digit2, Input::Action2), + (KeyCode::Digit3, Input::Action3), + (KeyCode::Digit4, Input::Action4), + (KeyCode::Digit5, Input::Action5), + (KeyCode::Digit6, Input::Action6), +]; + +pub struct InputManager { + pub screen_mouse_pos: Vec2, + pub world_mouse_pos: Vec2, + pub chunk_mouse_pos: IVec2, + pub local_mouse_pos: IVec2, + + pub lmb_pressed: bool, + pub lmb_held: bool, + pub rmb_pressed: bool, + pub rmb_held: bool, + pressed: [bool; INPUT_VAR_LEN], + held: [bool; INPUT_VAR_LEN], +} + +impl InputManager { + pub fn reset_for_frame(&mut self) { + self.pressed = [false; INPUT_VAR_LEN]; + self.lmb_pressed = false; + self.rmb_pressed = false; + } + + pub fn apply_event(&mut self, event: &WindowEvent, camera: &Camera) { + match event { + WindowEvent::KeyboardInput { + event: + KeyEvent { + physical_key: PhysicalKey::Code(code), + repeat: false, + state, + .. + }, + .. + } => { + if let Some(&(_, input)) = KEYMAP.iter().find(|m| m.0 == *code) { + if state.is_pressed() { + self.held[input as usize] = true; + self.pressed[input as usize] = true; + } else { + self.held[input as usize] = false; + } + } + } + WindowEvent::CursorMoved { position, .. } => { + let (wp_x, wp_y) = + camera.screen_position_to_world(position.x as f32, position.y as f32); + + let ((cx, cy), (lx, ly)) = + CellManager::split_game_position(wp_x.round() as i32, wp_y.round() as i32); + + self.screen_mouse_pos = Vec2::new(position.x as f32, position.y as f32); + self.world_mouse_pos = Vec2::new(wp_x, wp_y); + self.chunk_mouse_pos = IVec2::new(cx, cy); + self.local_mouse_pos = IVec2::new(lx as i32, ly as i32); + } + WindowEvent::MouseInput { state, button, .. } => { + if *button == MouseButton::Left { + if state.is_pressed() { + self.lmb_pressed = true; + self.lmb_held = true; + } else { + self.lmb_held = false; + } + } else if *button == MouseButton::Right { + if state.is_pressed() { + self.rmb_pressed = true; + self.rmb_held = true; + } else { + self.rmb_held = false; + } + } + } + _ => {} + } + } + + pub fn pressed(&self, input: Input) -> bool { + if input as usize >= INPUT_VAR_LEN { + false + } else { + self.pressed[input as usize] + } + } + + pub fn held(&self, input: Input) -> bool { + if input as usize >= INPUT_VAR_LEN { + false + } else { + self.held[input as usize] + } + } + + pub fn new() -> Self { + InputManager { + screen_mouse_pos: Vec2::ZERO, + world_mouse_pos: Vec2::ZERO, + chunk_mouse_pos: IVec2::ZERO, + local_mouse_pos: IVec2::ZERO, + + lmb_pressed: false, + lmb_held: false, + rmb_pressed: false, + rmb_held: false, + pressed: [false; INPUT_VAR_LEN], + held: [false; INPUT_VAR_LEN], + } + } +} |
