rsnaker/controls/
playing_input.rs1use crate::controls::direction::Direction;
2use crate::controls::main_menu::{ENTER_KEYS, NEXT_KEYS, PREVIOUS_KEYS};
3use crate::game_logic::state::{GameOverMenu, GameState, GameStatus};
4use crossterm::event;
5use crossterm::event::{KeyCode, KeyEventKind};
6use std::sync::{Arc, RwLock};
7
8pub const QUIT_KEYS: [KeyCode; 2] = [KeyCode::Char('q'), KeyCode::Char('Q')];
9pub const START_KEYS: [KeyCode; 2] = [KeyCode::Char('r'), KeyCode::Char('R')];
10pub const MAIN_MENU_KEYS: [KeyCode; 2] = [KeyCode::Char('m'), KeyCode::Char('M')];
11pub const PAUSE_KEYS: [KeyCode; 4] = [
13 KeyCode::Char('p'),
14 KeyCode::Char('P'),
15 KeyCode::Char(' '),
16 KeyCode::Home,
17];
18pub const RESET_KEYS: [KeyCode; 2] = [KeyCode::Char('r'), KeyCode::Char('R')];
19
20pub fn playing_input_loop(direction: &Arc<RwLock<Direction>>, gs: &Arc<RwLock<GameState>>) {
27 loop {
28 if let Ok(event::Event::Key(key)) = event::read() {
29 if key.kind == KeyEventKind::Press {
30 let mut gs_guard = gs.write().unwrap();
31 if let GameStatus::GameOver(selection) = gs_guard.status {
33 if NEXT_KEYS.contains(&key.code) {
34 gs_guard.status = GameStatus::GameOver(selection.next());
35 } else if PREVIOUS_KEYS.contains(&key.code) {
36 gs_guard.status = GameStatus::GameOver(selection.previous());
37 } else if ENTER_KEYS.contains(&key.code) {
38 match selection {
39 GameOverMenu::Restart => gs_guard.status = GameStatus::Restarting,
40 GameOverMenu::Menu => {
41 gs_guard.status = GameStatus::Menu;
42 break;
43 }
44 GameOverMenu::Quit => {
45 gs_guard.status = GameStatus::ByeBye;
46 break;
47 }
48 }
49 }
50 }
51 if PAUSE_KEYS.contains(&key.code) {
54 if gs_guard.status == GameStatus::Playing {
56 gs_guard.status = GameStatus::Paused;
57 } else if gs_guard.status == GameStatus::Paused {
58 gs_guard.status = GameStatus::Playing;
59 }
60 } else if QUIT_KEYS.contains(&key.code) {
62 gs_guard.status = GameStatus::ByeBye;
63 break;
64 } else if MAIN_MENU_KEYS.contains(&key.code) {
66 gs_guard.status = GameStatus::Menu;
67 break;
68 } else if RESET_KEYS.contains(&key.code) {
70 gs_guard.status = GameStatus::Restarting;
71 } else {
73 let direction_input = match key.code {
74 KeyCode::Left => Some(Direction::Left),
75 KeyCode::Right => Some(Direction::Right),
76 KeyCode::Down => Some(Direction::Down),
77 KeyCode::Up => Some(Direction::Up),
78 _ => None,
79 };
80 if let Some(dir) = direction_input {
81 *direction.write().unwrap() = dir;
82 }
83 }
84 }
85 }
86 }
87}