use sdl2::event::{Event, WindowEvent}; use sdl2::keyboard::Scancode; use sdl2::{EventPump, Sdl}; use specs::prelude::*; use crate::components::{Player, Velocity}; pub const PLAYER_SPEED: f64 = 150.; pub const ACTION_KEY_UP: u8 = 0b0001; pub const ACTION_KEY_LEFT: u8 = 0b0010; pub const ACTION_KEY_DOWN: u8 = 0b0100; pub const ACTION_KEY_RIGHT: u8 = 0b1000; pub struct SysInput { pressed_action_keys: u8, event_pump: EventPump, } impl SysInput { pub fn new(sdl: &Sdl) -> Self { Self { pressed_action_keys: 0b0, event_pump: sdl.event_pump().unwrap(), } } } impl<'a> System<'a> for SysInput { type SystemData = (WriteStorage<'a, Velocity>, ReadStorage<'a, Player>); fn run(&mut self, (mut vel, player): Self::SystemData) { let mut player_movement_changed = false; for event in self.event_pump.poll_iter() { match event { Event::Quit { .. } => { panic!("Quitting due to exit signal"); }, Event::Window { win_event: WindowEvent::Resized(x, y), .. } => { println!("Window resized to {}x{}", x, y); }, Event::KeyDown { scancode, .. } => match scancode { Some(Scancode::W) => { self.pressed_action_keys |= ACTION_KEY_UP; player_movement_changed = true; }, Some(Scancode::A) => { self.pressed_action_keys |= ACTION_KEY_LEFT; player_movement_changed = true; }, Some(Scancode::S) => { self.pressed_action_keys |= ACTION_KEY_DOWN; player_movement_changed = true; }, Some(Scancode::D) => { self.pressed_action_keys |= ACTION_KEY_RIGHT; player_movement_changed = true; }, key => { println!("keydown received: {:?}", key) }, }, Event::KeyUp { scancode, .. } => match scancode { Some(Scancode::W) => { self.pressed_action_keys &= !ACTION_KEY_UP; player_movement_changed = true; }, Some(Scancode::A) => { self.pressed_action_keys &= !ACTION_KEY_LEFT; player_movement_changed = true; }, Some(Scancode::S) => { self.pressed_action_keys &= !ACTION_KEY_DOWN; player_movement_changed = true; }, Some(Scancode::D) => { self.pressed_action_keys &= !ACTION_KEY_RIGHT; player_movement_changed = true; }, _ => {}, }, _ => {}, } } /* Update player movement */ if player_movement_changed { for (vel, _player) in (&mut vel, &player).join() { /* Vertical movement */ if (self.pressed_action_keys & ACTION_KEY_UP) != 0 { vel.0.y = -PLAYER_SPEED; } else if (self.pressed_action_keys & ACTION_KEY_DOWN) != 0 { vel.0.y = PLAYER_SPEED; } else { vel.0.y = 0.; } /* Horizontal movement */ if (self.pressed_action_keys & ACTION_KEY_LEFT) != 0 { vel.0.x = -PLAYER_SPEED; } else if (self.pressed_action_keys & ACTION_KEY_RIGHT) != 0 { vel.0.x = PLAYER_SPEED; } else { vel.0.x = 0.; } } } } }