Can fire with keyboard
This commit is contained in:
parent
454dff923b
commit
acd13af227
@ -18,7 +18,7 @@ use cli_player::server::start_server_if_missing;
|
|||||||
use cli_player::ui_screens::configure_game_rules::GameRulesConfigurationScreen;
|
use cli_player::ui_screens::configure_game_rules::GameRulesConfigurationScreen;
|
||||||
use cli_player::ui_screens::game_screen::GameScreen;
|
use cli_player::ui_screens::game_screen::GameScreen;
|
||||||
use cli_player::ui_screens::popup_screen::PopupScreen;
|
use cli_player::ui_screens::popup_screen::PopupScreen;
|
||||||
use cli_player::ui_screens::select_play_mode::{SelectPlayModeResult, SelectPlayModeScreen};
|
use cli_player::ui_screens::select_play_mode_screen::{SelectPlayModeResult, SelectPlayModeScreen};
|
||||||
use cli_player::ui_screens::*;
|
use cli_player::ui_screens::*;
|
||||||
use sea_battle_backend::data::GameRules;
|
use sea_battle_backend::data::GameRules;
|
||||||
use sea_battle_backend::human_player_ws::ServerMessage;
|
use sea_battle_backend::human_player_ws::ServerMessage;
|
||||||
@ -37,14 +37,14 @@ async fn run_dev<B: Backend>(
|
|||||||
.show(terminal)?
|
.show(terminal)?
|
||||||
.as_string(),
|
.as_string(),
|
||||||
TestDevScreen::Confirm => {
|
TestDevScreen::Confirm => {
|
||||||
confirm_dialog::ConfirmDialogScreen::new("Do you really want to quit game?")
|
confirm_dialog_screen::ConfirmDialogScreen::new("Do you really want to quit game?")
|
||||||
.show(terminal)?
|
.show(terminal)?
|
||||||
.as_string()
|
.as_string()
|
||||||
}
|
}
|
||||||
TestDevScreen::SelectBotType => select_bot_type::SelectBotTypeScreen::default()
|
TestDevScreen::SelectBotType => select_bot_type_screen::SelectBotTypeScreen::default()
|
||||||
.show(terminal)?
|
.show(terminal)?
|
||||||
.as_string(),
|
.as_string(),
|
||||||
TestDevScreen::SelectPlayMode => select_play_mode::SelectPlayModeScreen::default()
|
TestDevScreen::SelectPlayMode => select_play_mode_screen::SelectPlayModeScreen::default()
|
||||||
.show(terminal)?
|
.show(terminal)?
|
||||||
.as_string(),
|
.as_string(),
|
||||||
TestDevScreen::SetBoatsLayout => {
|
TestDevScreen::SetBoatsLayout => {
|
||||||
@ -53,7 +53,7 @@ async fn run_dev<B: Backend>(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
set_boats_layout::SetBoatsLayoutScreen::new(&rules)
|
set_boats_layout_screen::SetBoatsLayoutScreen::new(&rules)
|
||||||
.show(terminal)?
|
.show(terminal)?
|
||||||
.as_string()
|
.as_string()
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use tui::{Frame, Terminal};
|
|||||||
use sea_battle_backend::data::GameRules;
|
use sea_battle_backend::data::GameRules;
|
||||||
|
|
||||||
use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE};
|
use crate::constants::{HIGHLIGHT_COLOR, TICK_RATE};
|
||||||
use crate::ui_screens::select_bot_type::SelectBotTypeScreen;
|
use crate::ui_screens::select_bot_type_screen::SelectBotTypeScreen;
|
||||||
use crate::ui_screens::utils::centered_rect_size;
|
use crate::ui_screens::utils::centered_rect_size;
|
||||||
use crate::ui_screens::ScreenResult;
|
use crate::ui_screens::ScreenResult;
|
||||||
use crate::ui_widgets::button_widget::ButtonWidget;
|
use crate::ui_widgets::button_widget::ButtonWidget;
|
||||||
|
@ -3,20 +3,21 @@ use std::time::{Duration, Instant};
|
|||||||
|
|
||||||
use crossterm::event;
|
use crossterm::event;
|
||||||
use crossterm::event::{Event, KeyCode};
|
use crossterm::event::{Event, KeyCode};
|
||||||
use sea_battle_backend::data::{CurrentGameMapStatus, CurrentGameStatus};
|
|
||||||
use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage};
|
|
||||||
use sea_battle_backend::utils::Res;
|
|
||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Constraint, Direction, Layout};
|
use tui::layout::{Constraint, Direction, Layout};
|
||||||
use tui::style::Color;
|
use tui::style::Color;
|
||||||
use tui::widgets::Paragraph;
|
use tui::widgets::Paragraph;
|
||||||
use tui::{Frame, Terminal};
|
use tui::{Frame, Terminal};
|
||||||
|
|
||||||
|
use sea_battle_backend::data::{Coordinates, CurrentGameMapStatus, CurrentGameStatus};
|
||||||
|
use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage};
|
||||||
|
use sea_battle_backend::utils::Res;
|
||||||
|
|
||||||
use crate::client::Client;
|
use crate::client::Client;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::ui_screens::confirm_dialog::confirm;
|
use crate::ui_screens::confirm_dialog_screen::confirm;
|
||||||
use crate::ui_screens::popup_screen::PopupScreen;
|
use crate::ui_screens::popup_screen::PopupScreen;
|
||||||
use crate::ui_screens::set_boats_layout::SetBoatsLayoutScreen;
|
use crate::ui_screens::set_boats_layout_screen::SetBoatsLayoutScreen;
|
||||||
use crate::ui_screens::utils::{centered_rect_size, centered_text};
|
use crate::ui_screens::utils::{centered_rect_size, centered_text};
|
||||||
use crate::ui_screens::ScreenResult;
|
use crate::ui_screens::ScreenResult;
|
||||||
use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget};
|
use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget};
|
||||||
@ -54,7 +55,8 @@ pub struct GameScreen {
|
|||||||
client: Client,
|
client: Client,
|
||||||
status: GameStatus,
|
status: GameStatus,
|
||||||
opponent_name: Option<String>,
|
opponent_name: Option<String>,
|
||||||
game_status: CurrentGameStatus,
|
game: CurrentGameStatus,
|
||||||
|
curr_shoot_position: Coordinates,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameScreen {
|
impl GameScreen {
|
||||||
@ -63,7 +65,8 @@ impl GameScreen {
|
|||||||
client,
|
client,
|
||||||
status: GameStatus::Pending,
|
status: GameStatus::Pending,
|
||||||
opponent_name: None,
|
opponent_name: None,
|
||||||
game_status: Default::default(),
|
game: Default::default(),
|
||||||
|
curr_shoot_position: Coordinates::new(0, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +83,8 @@ impl GameScreen {
|
|||||||
// Handle terminal events
|
// Handle terminal events
|
||||||
if crossterm::event::poll(timeout)? {
|
if crossterm::event::poll(timeout)? {
|
||||||
if let Event::Key(key) = event::read()? {
|
if let Event::Key(key) = event::read()? {
|
||||||
|
let mut new_shoot_pos = self.curr_shoot_position;
|
||||||
|
|
||||||
match key.code {
|
match key.code {
|
||||||
// Leave game
|
// Leave game
|
||||||
KeyCode::Char('q')
|
KeyCode::Char('q')
|
||||||
@ -87,8 +92,28 @@ impl GameScreen {
|
|||||||
{
|
{
|
||||||
return Ok(ScreenResult::Canceled);
|
return Ok(ScreenResult::Canceled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move shoot cursor
|
||||||
|
KeyCode::Left if self.can_fire() => new_shoot_pos = new_shoot_pos.add_x(-1),
|
||||||
|
KeyCode::Right if self.can_fire() => new_shoot_pos = new_shoot_pos.add_x(1),
|
||||||
|
KeyCode::Up if self.can_fire() => new_shoot_pos = new_shoot_pos.add_y(-1),
|
||||||
|
KeyCode::Down if self.can_fire() => new_shoot_pos = new_shoot_pos.add_y(1),
|
||||||
|
|
||||||
|
// Shoot
|
||||||
|
KeyCode::Enter if self.can_fire() => {
|
||||||
|
if self.game.can_fire_at_location(self.curr_shoot_position) {
|
||||||
|
self.client.send_message(&ClientMessage::Fire {
|
||||||
|
location: self.curr_shoot_position,
|
||||||
|
}).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if new_shoot_pos.is_valid(&self.game.rules) {
|
||||||
|
self.curr_shoot_position = new_shoot_pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,12 +162,12 @@ impl GameScreen {
|
|||||||
|
|
||||||
ServerMessage::OpponentMustFire { status } => {
|
ServerMessage::OpponentMustFire { status } => {
|
||||||
self.status = GameStatus::OpponentMustFire;
|
self.status = GameStatus::OpponentMustFire;
|
||||||
self.game_status = status;
|
self.game = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerMessage::RequestFire { status } => {
|
ServerMessage::RequestFire { status } => {
|
||||||
self.status = GameStatus::MustFire;
|
self.status = GameStatus::MustFire;
|
||||||
self.game_status = status;
|
self.game = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerMessage::FireResult { .. } => {}
|
ServerMessage::FireResult { .. } => {}
|
||||||
@ -172,7 +197,20 @@ impl GameScreen {
|
|||||||
self.opponent_name.as_deref().unwrap_or("opponent")
|
self.opponent_name.as_deref().unwrap_or("opponent")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn player_map(&self, map: &CurrentGameMapStatus) -> GameMapWidget {
|
fn player_map(&self, map: &CurrentGameMapStatus, opponent_map: bool) -> GameMapWidget {
|
||||||
|
let mut map_widget = GameMapWidget::new(&self.game.rules);
|
||||||
|
|
||||||
|
// Current shoot position
|
||||||
|
if opponent_map {
|
||||||
|
map_widget = map_widget.add_colored_cells(ColoredCells {
|
||||||
|
color: match self.game.can_fire_at_location(self.curr_shoot_position) {
|
||||||
|
true => Color::Green,
|
||||||
|
false => Color::LightYellow,
|
||||||
|
},
|
||||||
|
cells: vec![self.curr_shoot_position],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Sunk boats
|
// Sunk boats
|
||||||
let sunk_boats = ColoredCells {
|
let sunk_boats = ColoredCells {
|
||||||
color: Color::Red,
|
color: Color::Red,
|
||||||
@ -206,7 +244,7 @@ impl GameScreen {
|
|||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
GameMapWidget::new(&self.game_status.rules)
|
map_widget
|
||||||
.add_colored_cells(sunk_boats)
|
.add_colored_cells(sunk_boats)
|
||||||
.add_colored_cells(touched_areas)
|
.add_colored_cells(touched_areas)
|
||||||
.add_colored_cells(failed_strikes)
|
.add_colored_cells(failed_strikes)
|
||||||
@ -227,16 +265,16 @@ impl GameScreen {
|
|||||||
|
|
||||||
// Draw main ui (default play UI)
|
// Draw main ui (default play UI)
|
||||||
let player_map = self
|
let player_map = self
|
||||||
.player_map(&self.game_status.your_map)
|
.player_map(&self.game.your_map, false)
|
||||||
.set_title("YOUR map");
|
.set_title("YOUR map");
|
||||||
|
|
||||||
let mut opponent_map = self
|
let mut opponent_map = self
|
||||||
.player_map(&self.game_status.opponent_map)
|
.player_map(&self.game.opponent_map, true)
|
||||||
.set_title(self.opponent_name());
|
.set_title(self.opponent_name());
|
||||||
|
|
||||||
if self.can_fire() {
|
if self.can_fire() {
|
||||||
opponent_map = opponent_map
|
opponent_map = opponent_map
|
||||||
.set_legend("Use arrows + enter\nor click on the place\nwhere you want\nto shoot");
|
.set_legend("Use arrows + Enter\nor click on the place\nwhere you want\nto shoot");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show both maps if there is enough room on the screen
|
// Show both maps if there is enough room on the screen
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub mod configure_game_rules;
|
pub mod configure_game_rules;
|
||||||
pub mod confirm_dialog;
|
pub mod confirm_dialog_screen;
|
||||||
pub mod game_screen;
|
pub mod game_screen;
|
||||||
pub mod input_screen;
|
pub mod input_screen;
|
||||||
pub mod popup_screen;
|
pub mod popup_screen;
|
||||||
pub mod select_bot_type;
|
pub mod select_bot_type_screen;
|
||||||
pub mod select_play_mode;
|
pub mod select_play_mode_screen;
|
||||||
pub mod set_boats_layout;
|
pub mod set_boats_layout_screen;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -13,7 +13,7 @@ use tui::{Frame, Terminal};
|
|||||||
use sea_battle_backend::data::*;
|
use sea_battle_backend::data::*;
|
||||||
|
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::ui_screens::confirm_dialog::confirm;
|
use crate::ui_screens::confirm_dialog_screen::confirm;
|
||||||
use crate::ui_screens::utils::{centered_rect_size, centered_text};
|
use crate::ui_screens::utils::{centered_rect_size, centered_text};
|
||||||
use crate::ui_screens::ScreenResult;
|
use crate::ui_screens::ScreenResult;
|
||||||
use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget};
|
use crate::ui_widgets::game_map_widget::{ColoredCells, GameMapWidget};
|
Loading…
Reference in New Issue
Block a user