From 20d922c56e2fd2a896f359f6123b67d8215c977d Mon Sep 17 00:00:00 2001 From: szymon Date: Fri, 21 Aug 2026 14:16:34 +0200 Subject: [PATCH] feat: add connecting to the server --- src/bin/macroquad_client.rs | 29 +++++++++++++++--- src/logic/board/board_view.rs | 2 +- src/ui/macroquad/difficulty_selection.rs | 11 +++---- src/ui/macroquad/game.rs | 38 ++++++++++++++++++++++++ src/ui/macroquad/main_menu.rs | 3 -- src/ui/macroquad/mod.rs | 1 + src/ui/macroquad/mode_selection.rs | 2 -- src/ui/macroquad/server_selection.rs | 5 ++-- src/ui/state.rs | 30 ++++++++++++++++--- 9 files changed, 99 insertions(+), 22 deletions(-) create mode 100644 src/ui/macroquad/game.rs diff --git a/src/bin/macroquad_client.rs b/src/bin/macroquad_client.rs index 1ecf02d..07762a1 100644 --- a/src/bin/macroquad_client.rs +++ b/src/bin/macroquad_client.rs @@ -9,9 +9,10 @@ use macroquad::{ color::{BLACK, WHITE}, math::vec2, miniquad::{self, conf::LinuxBackend::WaylandWithX11Fallback}, + text::draw_text, texture::{DrawTextureParams, draw_texture_ex, load_texture}, ui::{Skin, root_ui}, - window::{Conf, screen_height, screen_width}, + window::{Conf, next_frame, screen_height, screen_width}, }; fn window_conf() -> Conf { @@ -70,7 +71,7 @@ pub async fn main() { }, ); - match state { + match &state { GuiState::MainMenu => { draw_main_menu(&mut state).await; } @@ -87,16 +88,36 @@ pub async fn main() { draw_server_selection(&mut state, &mut context).await; } + GuiState::Connecting(receiver) => { + draw_text("Connecting...", 0.0, 0.0, 64.0, BLACK); + + match receiver.try_recv() { + Ok(client) => { + if let Some(client) = client { + draw_text("Connected!", 0.0, 0.0, 64.0, BLACK); + state = GuiState::Game(client); + } else { + draw_text("Could not connect!", 0.0, 0.0, 64.0, BLACK); + } + } + Err(_) => { + draw_text("Error", 0.0, 0.0, 64.0, BLACK); + } + } + } + GuiState::Settings => { todo!(); } - GuiState::Game => { - todo!(); + + GuiState::Game(client) => { + draw_text("Gamer time", 100.0, 100.0, 64.0, BLACK); } GuiState::Exit => { break; } } + next_frame().await; } } diff --git a/src/logic/board/board_view.rs b/src/logic/board/board_view.rs index c1b4828..4850edb 100644 --- a/src/logic/board/board_view.rs +++ b/src/logic/board/board_view.rs @@ -6,7 +6,7 @@ use uuid::Uuid; use crate::logic::board::{board::Board, field::Field}; /// View of the board, without any methods. Meant for sending over network -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)] pub struct BoardView { pub board: Vec, pub size: usize, diff --git a/src/ui/macroquad/difficulty_selection.rs b/src/ui/macroquad/difficulty_selection.rs index 090d682..8e32f5c 100644 --- a/src/ui/macroquad/difficulty_selection.rs +++ b/src/ui/macroquad/difficulty_selection.rs @@ -11,6 +11,7 @@ use crate::ui::{ state::{ GameContext, GuiState::{self}, + connect_to_server, }, }; @@ -30,25 +31,25 @@ pub async fn draw_dificulty_selection(state: &mut GuiState, context: &mut GameCo .ui(&mut root_ui(), |ui| { menu_builder.label(ui, "Difficulty Selection"); + // TODO! refactor this ugly ass code + if menu_builder.button(ui, "Easy") { context.difficulty = crate::super_advanced_ai::BotDificulty::Easy; - *state = GuiState::Game; + *state = GuiState::Connecting(connect_to_server(context.clone())); } if menu_builder.button(ui, "Medium") { context.difficulty = crate::super_advanced_ai::BotDificulty::Normal; - *state = GuiState::Game; + *state = GuiState::Connecting(connect_to_server(context.clone())); } if menu_builder.button(ui, "Hard") { context.difficulty = crate::super_advanced_ai::BotDificulty::Hard; - *state = GuiState::Game; + *state = GuiState::Connecting(connect_to_server(context.clone())); } if menu_builder.button(ui, "Go back") { *state = GuiState::ModeSelection; } }); - - next_frame().await; } diff --git a/src/ui/macroquad/game.rs b/src/ui/macroquad/game.rs new file mode 100644 index 0000000..2862c78 --- /dev/null +++ b/src/ui/macroquad/game.rs @@ -0,0 +1,38 @@ +use tokio::sync::mpsc::Receiver; + +use crate::{ + logic::board::board_view::BoardView, + network::{client::Client, message::ServerMessage}, + ui::state::GameContext, +}; + +pub struct GameClient { + client: Client, + update_receiver: Receiver, + + board: BoardView, + player_name: String, + enemy_name: String, // TODO! Server should give this info to us (it doesn't rn) +} + +impl GameClient { + pub async fn new(context: &GameContext) -> Option { + let Some(mut client) = Client::new(None).await else { + return None; + }; + + let Some(update_receiver) = client.get_update_receiver() else { + return None; + }; + + let board = BoardView::default(); + + Some(Self { + client, + update_receiver, + board, + player_name: "Morbius".to_string(), + enemy_name: "Milo".to_string(), + }) + } +} diff --git a/src/ui/macroquad/main_menu.rs b/src/ui/macroquad/main_menu.rs index d941fdd..5719574 100644 --- a/src/ui/macroquad/main_menu.rs +++ b/src/ui/macroquad/main_menu.rs @@ -8,7 +8,6 @@ use macroquad::{ use crate::ui::{macroquad::menu_builder::MenuBuilder, state::GuiState}; - pub async fn draw_main_menu(state: &mut GuiState) { let menu_size = vec2(screen_width() * 0.5, screen_height() * 0.5); let menu_pos = vec2( @@ -37,6 +36,4 @@ pub async fn draw_main_menu(state: &mut GuiState) { *state = GuiState::Exit; } }); - - next_frame().await; } diff --git a/src/ui/macroquad/mod.rs b/src/ui/macroquad/mod.rs index 3b2fad6..03200bd 100644 --- a/src/ui/macroquad/mod.rs +++ b/src/ui/macroquad/mod.rs @@ -1,4 +1,5 @@ pub mod difficulty_selection; +pub mod game; pub mod main_menu; mod menu_builder; pub mod mode_selection; diff --git a/src/ui/macroquad/mode_selection.rs b/src/ui/macroquad/mode_selection.rs index f89b301..93bb956 100644 --- a/src/ui/macroquad/mode_selection.rs +++ b/src/ui/macroquad/mode_selection.rs @@ -43,6 +43,4 @@ pub async fn draw_mode_selection(state: &mut GuiState, context: &mut GameContext *state = GuiState::MainMenu; } }); - - next_frame().await; } diff --git a/src/ui/macroquad/server_selection.rs b/src/ui/macroquad/server_selection.rs index 359ba24..605b451 100644 --- a/src/ui/macroquad/server_selection.rs +++ b/src/ui/macroquad/server_selection.rs @@ -11,6 +11,7 @@ use crate::ui::{ state::{ GameContext, GuiState::{self}, + connect_to_server, }, }; @@ -40,7 +41,7 @@ pub async fn draw_server_selection(state: &mut GuiState, context: &mut GameConte if menu_builder.button(ui, "Connect") { context.gamemode = crate::ui::state::GameMode::Multiplayer { is_hosting: false }; - *state = GuiState::Game; + *state = GuiState::Connecting(connect_to_server(context.clone())); // TODO Validate url before connecting or something like that } @@ -48,6 +49,4 @@ pub async fn draw_server_selection(state: &mut GuiState, context: &mut GameConte *state = GuiState::ModeSelection; } }); - - next_frame().await; } diff --git a/src/ui/state.rs b/src/ui/state.rs index 093eec3..a782c16 100644 --- a/src/ui/state.rs +++ b/src/ui/state.rs @@ -1,4 +1,6 @@ -use crate::super_advanced_ai::BotDificulty; +use std::sync::mpsc::{self, Receiver}; + +use crate::{super_advanced_ai::BotDificulty, ui::macroquad::game::GameClient}; #[derive(Default)] pub enum GuiState { @@ -9,12 +11,14 @@ pub enum GuiState { DificultySelection, ServerSelection, + Connecting(Receiver>), + Settings, - Game, + Game(GameClient), Exit, } -#[derive(Default)] +#[derive(Default, Clone, Copy)] pub enum GameMode { #[default] Singleplayer, @@ -23,9 +27,27 @@ pub enum GameMode { }, } -#[derive(Default)] +#[derive(Default, Clone)] pub struct GameContext { pub difficulty: BotDificulty, pub gamemode: GameMode, pub server_url_buffer: String, } + +// TODO! Move this +pub fn connect_to_server(context: GameContext) -> Receiver> { + let (tx, rc) = mpsc::channel::>(); + let context_clone = context.clone(); + + let _ = std::thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + + let client_option = rt.block_on(async { GameClient::new(&context_clone).await }); + + let _ = tx.send(client_option); + + std::thread::park(); + }); + + rc +}