mirror of
https://github.com/szymon-jozef/checkers.git
synced 2026-10-27 19:20:44 +01:00
feat: add connecting to the server
This commit is contained in:
@@ -9,9 +9,10 @@ use macroquad::{
|
|||||||
color::{BLACK, WHITE},
|
color::{BLACK, WHITE},
|
||||||
math::vec2,
|
math::vec2,
|
||||||
miniquad::{self, conf::LinuxBackend::WaylandWithX11Fallback},
|
miniquad::{self, conf::LinuxBackend::WaylandWithX11Fallback},
|
||||||
|
text::draw_text,
|
||||||
texture::{DrawTextureParams, draw_texture_ex, load_texture},
|
texture::{DrawTextureParams, draw_texture_ex, load_texture},
|
||||||
ui::{Skin, root_ui},
|
ui::{Skin, root_ui},
|
||||||
window::{Conf, screen_height, screen_width},
|
window::{Conf, next_frame, screen_height, screen_width},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn window_conf() -> Conf {
|
fn window_conf() -> Conf {
|
||||||
@@ -70,7 +71,7 @@ pub async fn main() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
match state {
|
match &state {
|
||||||
GuiState::MainMenu => {
|
GuiState::MainMenu => {
|
||||||
draw_main_menu(&mut state).await;
|
draw_main_menu(&mut state).await;
|
||||||
}
|
}
|
||||||
@@ -87,16 +88,36 @@ pub async fn main() {
|
|||||||
draw_server_selection(&mut state, &mut context).await;
|
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 => {
|
GuiState::Settings => {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
GuiState::Game => {
|
|
||||||
todo!();
|
GuiState::Game(client) => {
|
||||||
|
draw_text("Gamer time", 100.0, 100.0, 64.0, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiState::Exit => {
|
GuiState::Exit => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next_frame().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use uuid::Uuid;
|
|||||||
use crate::logic::board::{board::Board, field::Field};
|
use crate::logic::board::{board::Board, field::Field};
|
||||||
|
|
||||||
/// View of the board, without any methods. Meant for sending over network
|
/// 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 struct BoardView {
|
||||||
pub board: Vec<Field>,
|
pub board: Vec<Field>,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::ui::{
|
|||||||
state::{
|
state::{
|
||||||
GameContext,
|
GameContext,
|
||||||
GuiState::{self},
|
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| {
|
.ui(&mut root_ui(), |ui| {
|
||||||
menu_builder.label(ui, "Difficulty Selection");
|
menu_builder.label(ui, "Difficulty Selection");
|
||||||
|
|
||||||
|
// TODO! refactor this ugly ass code
|
||||||
|
|
||||||
if menu_builder.button(ui, "Easy") {
|
if menu_builder.button(ui, "Easy") {
|
||||||
context.difficulty = crate::super_advanced_ai::BotDificulty::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") {
|
if menu_builder.button(ui, "Medium") {
|
||||||
context.difficulty = crate::super_advanced_ai::BotDificulty::Normal;
|
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") {
|
if menu_builder.button(ui, "Hard") {
|
||||||
context.difficulty = crate::super_advanced_ai::BotDificulty::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") {
|
if menu_builder.button(ui, "Go back") {
|
||||||
*state = GuiState::ModeSelection;
|
*state = GuiState::ModeSelection;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
next_frame().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/ui/macroquad/game.rs
Normal file
38
src/ui/macroquad/game.rs
Normal file
@@ -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<ServerMessage>,
|
||||||
|
|
||||||
|
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<Self> {
|
||||||
|
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(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ use macroquad::{
|
|||||||
|
|
||||||
use crate::ui::{macroquad::menu_builder::MenuBuilder, state::GuiState};
|
use crate::ui::{macroquad::menu_builder::MenuBuilder, state::GuiState};
|
||||||
|
|
||||||
|
|
||||||
pub async fn draw_main_menu(state: &mut GuiState) {
|
pub async fn draw_main_menu(state: &mut GuiState) {
|
||||||
let menu_size = vec2(screen_width() * 0.5, screen_height() * 0.5);
|
let menu_size = vec2(screen_width() * 0.5, screen_height() * 0.5);
|
||||||
let menu_pos = vec2(
|
let menu_pos = vec2(
|
||||||
@@ -37,6 +36,4 @@ pub async fn draw_main_menu(state: &mut GuiState) {
|
|||||||
*state = GuiState::Exit;
|
*state = GuiState::Exit;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
next_frame().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod difficulty_selection;
|
pub mod difficulty_selection;
|
||||||
|
pub mod game;
|
||||||
pub mod main_menu;
|
pub mod main_menu;
|
||||||
mod menu_builder;
|
mod menu_builder;
|
||||||
pub mod mode_selection;
|
pub mod mode_selection;
|
||||||
|
|||||||
@@ -43,6 +43,4 @@ pub async fn draw_mode_selection(state: &mut GuiState, context: &mut GameContext
|
|||||||
*state = GuiState::MainMenu;
|
*state = GuiState::MainMenu;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
next_frame().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::ui::{
|
|||||||
state::{
|
state::{
|
||||||
GameContext,
|
GameContext,
|
||||||
GuiState::{self},
|
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") {
|
if menu_builder.button(ui, "Connect") {
|
||||||
context.gamemode = crate::ui::state::GameMode::Multiplayer { is_hosting: false };
|
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
|
// 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;
|
*state = GuiState::ModeSelection;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
next_frame().await;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)]
|
#[derive(Default)]
|
||||||
pub enum GuiState {
|
pub enum GuiState {
|
||||||
@@ -9,12 +11,14 @@ pub enum GuiState {
|
|||||||
DificultySelection,
|
DificultySelection,
|
||||||
ServerSelection,
|
ServerSelection,
|
||||||
|
|
||||||
|
Connecting(Receiver<Option<GameClient>>),
|
||||||
|
|
||||||
Settings,
|
Settings,
|
||||||
Game,
|
Game(GameClient),
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub enum GameMode {
|
pub enum GameMode {
|
||||||
#[default]
|
#[default]
|
||||||
Singleplayer,
|
Singleplayer,
|
||||||
@@ -23,9 +27,27 @@ pub enum GameMode {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub struct GameContext {
|
pub struct GameContext {
|
||||||
pub difficulty: BotDificulty,
|
pub difficulty: BotDificulty,
|
||||||
pub gamemode: GameMode,
|
pub gamemode: GameMode,
|
||||||
pub server_url_buffer: String,
|
pub server_url_buffer: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO! Move this
|
||||||
|
pub fn connect_to_server(context: GameContext) -> Receiver<Option<GameClient>> {
|
||||||
|
let (tx, rc) = mpsc::channel::<Option<GameClient>>();
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user