Can fire with mouse
This commit is contained in:
parent
acd13af227
commit
3455559d33
@ -1,8 +1,9 @@
|
|||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use crossterm::event;
|
use crossterm::event;
|
||||||
use crossterm::event::{Event, KeyCode};
|
use crossterm::event::{Event, KeyCode, MouseButton, MouseEventKind};
|
||||||
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;
|
||||||
@ -22,6 +23,8 @@ 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};
|
||||||
|
|
||||||
|
type CoordinatesMapper = HashMap<Coordinates, Coordinates>;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
enum GameStatus {
|
enum GameStatus {
|
||||||
Pending,
|
Pending,
|
||||||
@ -72,9 +75,12 @@ impl GameScreen {
|
|||||||
|
|
||||||
pub async fn show<B: Backend>(mut self, terminal: &mut Terminal<B>) -> Res<ScreenResult> {
|
pub async fn show<B: Backend>(mut self, terminal: &mut Terminal<B>) -> Res<ScreenResult> {
|
||||||
let mut last_tick = Instant::now();
|
let mut last_tick = Instant::now();
|
||||||
|
|
||||||
|
let mut coordinates_mapper = CoordinatesMapper::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Update UI
|
// Update UI
|
||||||
terminal.draw(|f| self.ui(f))?;
|
terminal.draw(|f| coordinates_mapper = self.ui(f))?;
|
||||||
|
|
||||||
let timeout = TICK_RATE
|
let timeout = TICK_RATE
|
||||||
.checked_sub(last_tick.elapsed())
|
.checked_sub(last_tick.elapsed())
|
||||||
@ -82,7 +88,10 @@ 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()? {
|
let event = event::read()?;
|
||||||
|
|
||||||
|
// Keyboard event
|
||||||
|
if let Event::Key(key) = &event {
|
||||||
let mut new_shoot_pos = self.curr_shoot_position;
|
let mut new_shoot_pos = self.curr_shoot_position;
|
||||||
|
|
||||||
match key.code {
|
match key.code {
|
||||||
@ -102,9 +111,11 @@ impl GameScreen {
|
|||||||
// Shoot
|
// Shoot
|
||||||
KeyCode::Enter if self.can_fire() => {
|
KeyCode::Enter if self.can_fire() => {
|
||||||
if self.game.can_fire_at_location(self.curr_shoot_position) {
|
if self.game.can_fire_at_location(self.curr_shoot_position) {
|
||||||
self.client.send_message(&ClientMessage::Fire {
|
self.client
|
||||||
|
.send_message(&ClientMessage::Fire {
|
||||||
location: self.curr_shoot_position,
|
location: self.curr_shoot_position,
|
||||||
}).await?;
|
})
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +126,17 @@ impl GameScreen {
|
|||||||
self.curr_shoot_position = new_shoot_pos;
|
self.curr_shoot_position = new_shoot_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mouse event
|
||||||
|
if let Event::Mouse(mouse) = event {
|
||||||
|
if mouse.kind == MouseEventKind::Up(MouseButton::Left) {
|
||||||
|
if let Some(c) =
|
||||||
|
coordinates_mapper.get(&Coordinates::new(mouse.column, mouse.row))
|
||||||
|
{
|
||||||
|
self.curr_shoot_position = *c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle incoming messages
|
// Handle incoming messages
|
||||||
@ -213,7 +235,7 @@ impl GameScreen {
|
|||||||
|
|
||||||
// Sunk boats
|
// Sunk boats
|
||||||
let sunk_boats = ColoredCells {
|
let sunk_boats = ColoredCells {
|
||||||
color: Color::Red,
|
color: Color::Gray,
|
||||||
cells: map
|
cells: map
|
||||||
.sunk_boats
|
.sunk_boats
|
||||||
.iter()
|
.iter()
|
||||||
@ -223,13 +245,13 @@ impl GameScreen {
|
|||||||
|
|
||||||
// Touched boats
|
// Touched boats
|
||||||
let touched_areas = ColoredCells {
|
let touched_areas = ColoredCells {
|
||||||
color: Color::Rgb(245, 45, 7),
|
color: Color::Red,
|
||||||
cells: map.successful_strikes.clone(),
|
cells: map.successful_strikes.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Failed strikes
|
// Failed strikes
|
||||||
let failed_strikes = ColoredCells {
|
let failed_strikes = ColoredCells {
|
||||||
color: Color::Gray,
|
color: Color::DarkGray,
|
||||||
cells: map.failed_strikes.clone(),
|
cells: map.failed_strikes.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,7 +273,7 @@ impl GameScreen {
|
|||||||
.add_colored_cells(boats)
|
.add_colored_cells(boats)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui<B: Backend>(&mut self, f: &mut Frame<B>) {
|
fn ui<B: Backend>(&mut self, f: &mut Frame<B>) -> CoordinatesMapper {
|
||||||
let status_text = self
|
let status_text = self
|
||||||
.status
|
.status
|
||||||
.status_text()
|
.status_text()
|
||||||
@ -260,7 +282,7 @@ impl GameScreen {
|
|||||||
// If the game is in a state where game maps can not be shown
|
// If the game is in a state where game maps can not be shown
|
||||||
if !self.status.can_show_game_maps() {
|
if !self.status.can_show_game_maps() {
|
||||||
PopupScreen::new(&status_text).show_in_frame(f);
|
PopupScreen::new(&status_text).show_in_frame(f);
|
||||||
return;
|
return HashMap::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw main ui (default play UI)
|
// Draw main ui (default play UI)
|
||||||
@ -268,9 +290,17 @@ impl GameScreen {
|
|||||||
.player_map(&self.game.your_map, false)
|
.player_map(&self.game.your_map, false)
|
||||||
.set_title("YOUR map");
|
.set_title("YOUR map");
|
||||||
|
|
||||||
|
let mut coordinates_mapper = HashMap::new();
|
||||||
let mut opponent_map = self
|
let mut opponent_map = self
|
||||||
.player_map(&self.game.opponent_map, true)
|
.player_map(&self.game.opponent_map, true)
|
||||||
.set_title(self.opponent_name());
|
.set_title(self.opponent_name())
|
||||||
|
.set_yield_func(|c, r| {
|
||||||
|
for i in 0..r.width {
|
||||||
|
for j in 0..r.height {
|
||||||
|
coordinates_mapper.insert(Coordinates::new(r.x + i, r.y + j), c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if self.can_fire() {
|
if self.can_fire() {
|
||||||
opponent_map = opponent_map
|
opponent_map = opponent_map
|
||||||
@ -295,7 +325,7 @@ impl GameScreen {
|
|||||||
// Check if frame is too small
|
// Check if frame is too small
|
||||||
if max_width > f.size().width || total_height > f.size().height {
|
if max_width > f.size().width || total_height > f.size().height {
|
||||||
PopupScreen::new("Screen too small!").show_in_frame(f);
|
PopupScreen::new("Screen too small!").show_in_frame(f);
|
||||||
return;
|
return HashMap::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
@ -330,10 +360,13 @@ impl GameScreen {
|
|||||||
f.render_widget(opponent_map, chunks[1]);
|
f.render_widget(opponent_map, chunks[1]);
|
||||||
} else {
|
} else {
|
||||||
f.render_widget(player_map, chunks[1]);
|
f.render_widget(player_map, chunks[1]);
|
||||||
|
drop(opponent_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render buttons
|
// Render buttons
|
||||||
// TODO : at the end of the game
|
// TODO : at the end of the game
|
||||||
|
|
||||||
|
coordinates_mapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user