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