use ggez::{Context, GameResult}; use crate::bitfield; use crate::common::Rect; use crate::input::player_controller::PlayerController; use crate::input::touch_controls::TouchControlType; use crate::shared_game_state::SharedGameState; /// A no-op implementation of player controller. #[derive(Clone)] pub struct TouchPlayerController { state: KeyState, old_state: KeyState, trigger: KeyState, prev_touch_len: usize, } bitfield! { #[derive(Clone, Copy)] pub struct KeyState(u16); impl Debug; pub left, set_left: 0; pub right, set_right: 1; pub up, set_up: 2; pub down, set_down: 3; pub map, set_map: 4; pub inventory, set_inventory: 5; pub jump, set_jump: 6; pub shoot, set_shoot: 7; pub next_weapon, set_next_weapon: 8; pub prev_weapon, set_prev_weapon: 9; pub pause, set_pause: 10; } impl TouchPlayerController { pub fn new() -> TouchPlayerController { TouchPlayerController { state: KeyState(0), old_state: KeyState(0), trigger: KeyState(0), prev_touch_len: 0, } } } impl PlayerController for TouchPlayerController { fn update(&mut self, state: &mut SharedGameState, _ctx: &mut Context) -> GameResult { match state.touch_controls.control_type { TouchControlType::None => {} TouchControlType::Dialog => { self.state.set_jump(state.touch_controls.point_in(Rect::new_size(0, 0, state.canvas_size.0 as isize, state.canvas_size.1 as isize)).is_some()); if state.touch_controls.points.len() > 1 && self.prev_touch_len != state.touch_controls.points.len() { self.prev_touch_len = state.touch_controls.points.len(); self.old_state.set_jump(false); } } TouchControlType::Controls => { self.state.0 = 0; // left self.state.set_left(self.state.left() || state.touch_controls.point_in(Rect::new_size(4, state.canvas_size.1 as isize - 4 - 48 * 2, 48, 48)).is_some()); // up self.state.set_up(self.state.up() || state.touch_controls.point_in(Rect::new_size(48 + 4, state.canvas_size.1 as isize - 4 - 48 * 3, 48, 48)).is_some()); // right self.state.set_right(self.state.right() || state.touch_controls.point_in(Rect::new_size(4 + 48 * 2, state.canvas_size.1 as isize - 4 - 48 * 2, 48, 48)).is_some()); // down self.state.set_down(self.state.down() || state.touch_controls.point_in(Rect::new_size(48 + 4, state.canvas_size.1 as isize - 4 - 48, 48, 48)).is_some()); // left+up self.state.set_left(self.state.left() || state.touch_controls.point_in(Rect::new_size(4, state.canvas_size.1 as isize - 4 - 48 * 3, 48, 48)).is_some()); self.state.set_up(self.state.up() || state.touch_controls.point_in(Rect::new_size(4, state.canvas_size.1 as isize - 4 - 48 * 3, 48, 48)).is_some()); // right+up self.state.set_right(self.state.right() || state.touch_controls.point_in(Rect::new_size(4 + 48 * 2, state.canvas_size.1 as isize - 4 - 48 * 3, 48, 48)).is_some()); self.state.set_up(self.state.up() || state.touch_controls.point_in(Rect::new_size(4 + 48 * 2, state.canvas_size.1 as isize - 4 - 48 * 3, 48, 48)).is_some()); // left+down self.state.set_left(self.state.left() || state.touch_controls.point_in(Rect::new_size(4, state.canvas_size.1 as isize - 48 - 4, 48, 48)).is_some()); self.state.set_down(self.state.down() || state.touch_controls.point_in(Rect::new_size(4, state.canvas_size.1 as isize - 48 - 4, 48, 48)).is_some()); // right+down self.state.set_right(self.state.right() || state.touch_controls.point_in(Rect::new_size(4 + 48 * 2, state.canvas_size.1 as isize - 48 - 4, 48, 48)).is_some()); self.state.set_down(self.state.down() || state.touch_controls.point_in(Rect::new_size(4 + 48 * 2, state.canvas_size.1 as isize - 48 - 4, 48, 48)).is_some()); self.state.set_jump(self.state.jump() || state.touch_controls.point_in(Rect::new_size(state.canvas_size.0 as isize - 48 - 4, state.canvas_size.1 as isize - 48 - 4, 48, 48)).is_some()); self.state.set_shoot(self.state.shoot() || state.touch_controls.point_in(Rect::new_size(state.canvas_size.0 as isize - 48 - 4, state.canvas_size.1 as isize - (48 - 4) * 2, 48, 48)).is_some()); } } Ok(()) } fn update_trigger(&mut self) { let mut trigger = self.state.0 ^ self.old_state.0; trigger &= self.state.0; self.old_state = self.state; self.trigger = KeyState(trigger); } fn move_up(&self) -> bool { self.state.up() } fn move_left(&self) -> bool { self.state.left() } fn move_down(&self) -> bool { self.state.down() } fn move_right(&self) -> bool { self.state.right() } fn prev_weapon(&self) -> bool { self.state.prev_weapon() } fn next_weapon(&self) -> bool { self.state.next_weapon() } fn jump(&self) -> bool { self.state.jump() } fn shoot(&self) -> bool { self.state.shoot() } fn trigger_up(&self) -> bool { self.trigger.up() } fn trigger_left(&self) -> bool { self.trigger.left() } fn trigger_down(&self) -> bool { self.trigger.down() } fn trigger_right(&self) -> bool { self.trigger.right() } fn trigger_prev_weapon(&self) -> bool { self.trigger.prev_weapon() } fn trigger_next_weapon(&self) -> bool { self.trigger.next_weapon() } fn trigger_jump(&self) -> bool { self.trigger.jump() } fn trigger_shoot(&self) -> bool { self.trigger.shoot() } fn trigger_menu_ok(&self) -> bool { self.trigger.jump() } fn trigger_menu_back(&self) -> bool { self.trigger.shoot() } fn trigger_menu_pause(&self) -> bool { self.trigger.pause() } fn look_up(&self) -> bool { self.state.up() } fn look_left(&self) -> bool { self.state.left() } fn look_down(&self) -> bool { self.state.down() } fn look_right(&self) -> bool { self.state.right() } fn move_analog_x(&self) -> f64 { if self.state.left() && self.state.right() { 0.0 } else if self.state.left() { -1.0 } else if self.state.right() { 1.0 } else { 0.0 } } fn move_analog_y(&self) -> f64 { if self.state.up() && self.state.down() { 0.0 } else if self.state.up() { -1.0 } else if self.state.down() { 1.0 } else { 0.0 } } }