mirror of
https://github.com/szymon-jozef/checkers.git
synced 2026-10-27 19:20:44 +01:00
feat: add lobby checkbox that does nothing at the moment
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
use checkers::ui::{
|
use checkers::ui::{
|
||||||
macroquad::{
|
macroquad::{
|
||||||
difficulty_selection::draw_dificulty_selection, main_menu::draw_main_menu,
|
difficulty_selection::draw_dificulty_selection, game::GameClient,
|
||||||
mode_selection::draw_mode_selection, server_selection::draw_server_selection,
|
main_menu::draw_main_menu, mode_selection::draw_mode_selection,
|
||||||
|
server_selection::draw_server_selection,
|
||||||
},
|
},
|
||||||
state::{GameContext, GuiState},
|
state::{GameContext, GuiState},
|
||||||
};
|
};
|
||||||
@@ -40,9 +41,16 @@ pub async fn get_general_style() -> Skin {
|
|||||||
.font_size(32)
|
.font_size(32)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let checkbox_style = root_ui()
|
||||||
|
.style_builder()
|
||||||
|
.color(BLACK)
|
||||||
|
.text_color(BLACK)
|
||||||
|
.build();
|
||||||
|
|
||||||
Skin {
|
Skin {
|
||||||
label_style,
|
label_style,
|
||||||
button_style,
|
button_style,
|
||||||
|
checkbox_style,
|
||||||
..root_ui().default_skin()
|
..root_ui().default_skin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +79,7 @@ pub async fn main() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
match &state {
|
match &mut state {
|
||||||
GuiState::MainMenu => {
|
GuiState::MainMenu => {
|
||||||
draw_main_menu(&mut state).await;
|
draw_main_menu(&mut state).await;
|
||||||
}
|
}
|
||||||
@@ -95,7 +103,13 @@ pub async fn main() {
|
|||||||
Ok(client) => {
|
Ok(client) => {
|
||||||
if let Some(client) = client {
|
if let Some(client) = client {
|
||||||
draw_text("Connected!", 0.0, 0.0, 64.0, BLACK);
|
draw_text("Connected!", 0.0, 0.0, 64.0, BLACK);
|
||||||
|
let client = GameClient::new(client, &context);
|
||||||
|
if let Some(client) = client {
|
||||||
state = GuiState::Game(client);
|
state = GuiState::Game(client);
|
||||||
|
} else {
|
||||||
|
// ugly ass code
|
||||||
|
draw_text("Could not connect!", 0.0, 0.0, 64.0, BLACK);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
draw_text("Could not connect!", 0.0, 0.0, 64.0, BLACK);
|
draw_text("Could not connect!", 0.0, 0.0, 64.0, BLACK);
|
||||||
}
|
}
|
||||||
@@ -111,7 +125,8 @@ pub async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GuiState::Game(client) => {
|
GuiState::Game(client) => {
|
||||||
draw_text("Gamer time", 100.0, 100.0, 64.0, BLACK);
|
client.update();
|
||||||
|
client.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiState::Exit => {
|
GuiState::Exit => {
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ const MAX_PLAYABLE_CONNECTIONS: usize = 2; // DON'T EVER CHANGE THIS AS GAME OF
|
|||||||
// There will be a spectator mode, hence the name __PLAYABLE__ connection. You will be able to have
|
// There will be a spectator mode, hence the name __PLAYABLE__ connection. You will be able to have
|
||||||
// more connections, but they won't be able to play
|
// more connections, but they won't be able to play
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
enum ServerStage {
|
pub enum ServerStage {
|
||||||
|
#[default]
|
||||||
Lobby,
|
Lobby,
|
||||||
Game,
|
Game,
|
||||||
End,
|
End,
|
||||||
|
|||||||
@@ -35,17 +35,17 @@ pub async fn draw_dificulty_selection(state: &mut GuiState, context: &mut GameCo
|
|||||||
|
|
||||||
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::Connecting(connect_to_server(context.clone()));
|
*state = GuiState::Connecting(connect_to_server());
|
||||||
}
|
}
|
||||||
|
|
||||||
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::Connecting(connect_to_server(context.clone()));
|
*state = GuiState::Connecting(connect_to_server());
|
||||||
}
|
}
|
||||||
|
|
||||||
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::Connecting(connect_to_server(context.clone()));
|
*state = GuiState::Connecting(connect_to_server());
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu_builder.button(ui, "Go back") {
|
if menu_builder.button(ui, "Go back") {
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
use tokio::sync::mpsc::Receiver;
|
use log::{error, info};
|
||||||
|
use macroquad::{
|
||||||
|
color::GRAY,
|
||||||
|
math::{Rect, Vec2, vec2},
|
||||||
|
shapes::draw_rectangle,
|
||||||
|
ui::{Ui, hash, root_ui, widgets::Checkbox},
|
||||||
|
window::{screen_height, screen_width},
|
||||||
|
};
|
||||||
|
use tokio::sync::mpsc::{Receiver, error::TryRecvError::Disconnected};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
logic::board::board_view::BoardView,
|
logic::board::board_view::BoardView,
|
||||||
network::{client::Client, message::ServerMessage},
|
network::{
|
||||||
|
client::Client, message::ServerMessage, network_identity::NetworkIdentity,
|
||||||
|
server::ServerStage,
|
||||||
|
},
|
||||||
ui::state::GameContext,
|
ui::state::GameContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10,29 +21,182 @@ pub struct GameClient {
|
|||||||
client: Client,
|
client: Client,
|
||||||
update_receiver: Receiver<ServerMessage>,
|
update_receiver: Receiver<ServerMessage>,
|
||||||
|
|
||||||
|
identity: Option<NetworkIdentity>,
|
||||||
|
|
||||||
board: BoardView,
|
board: BoardView,
|
||||||
player_name: String,
|
player_name: String,
|
||||||
enemy_name: String, // TODO! Server should give this info to us (it doesn't rn)
|
enemy_name: String, // TODO! Server should give this info to us (it doesn't rn)
|
||||||
|
|
||||||
|
game_state: ServerStage,
|
||||||
|
|
||||||
|
game_area: Rect,
|
||||||
|
game_padding: f32,
|
||||||
|
|
||||||
|
lobby: Lobby,
|
||||||
|
|
||||||
|
chat_area: Rect,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Lobby {
|
||||||
|
is_ready: bool,
|
||||||
|
checkbox_pos: Vec2,
|
||||||
|
checkbox_size: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameClient {
|
impl GameClient {
|
||||||
pub async fn new(context: &GameContext) -> Option<Self> {
|
pub fn new(mut client: Client, context: &GameContext) -> Option<Self> {
|
||||||
let Some(mut client) = Client::new(None).await else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(update_receiver) = client.get_update_receiver() else {
|
let Some(update_receiver) = client.get_update_receiver() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let board = BoardView::default();
|
let board = BoardView::default();
|
||||||
|
|
||||||
|
let game_stage = ServerStage::default();
|
||||||
|
let mut lobby = Lobby::default();
|
||||||
|
lobby.checkbox_size = vec2(32.0, 16.0);
|
||||||
|
|
||||||
|
let game_area = Rect {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
w: screen_width() * 0.8,
|
||||||
|
h: screen_height(),
|
||||||
|
};
|
||||||
|
let game_padding = 25.0;
|
||||||
|
|
||||||
|
let chat_area = Rect {
|
||||||
|
x: game_area.w,
|
||||||
|
y: 0.0,
|
||||||
|
w: screen_width() * 0.2,
|
||||||
|
h: screen_height(),
|
||||||
|
};
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
client,
|
client,
|
||||||
update_receiver,
|
update_receiver,
|
||||||
|
identity: None,
|
||||||
|
|
||||||
board,
|
board,
|
||||||
|
lobby,
|
||||||
|
|
||||||
player_name: "Morbius".to_string(),
|
player_name: "Morbius".to_string(),
|
||||||
enemy_name: "Milo".to_string(),
|
enemy_name: "Milo".to_string(),
|
||||||
|
|
||||||
|
game_state: game_stage,
|
||||||
|
|
||||||
|
game_area,
|
||||||
|
game_padding,
|
||||||
|
|
||||||
|
chat_area,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw(&mut self) {
|
||||||
|
match self.game_state {
|
||||||
|
ServerStage::Lobby => {
|
||||||
|
self.draw_lobby();
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerStage::Game => {
|
||||||
|
self.draw_game();
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerStage::End => {
|
||||||
|
self.draw_summary_screen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//self.draw_chat(); // TODO! uncomment this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_lobby(&mut self) {
|
||||||
|
let lobby = &self.lobby;
|
||||||
|
|
||||||
|
draw_rectangle(
|
||||||
|
lobby.checkbox_pos.x,
|
||||||
|
lobby.checkbox_pos.y,
|
||||||
|
lobby.checkbox_size.x * 10.0,
|
||||||
|
lobby.checkbox_size.y * 10.0,
|
||||||
|
GRAY,
|
||||||
|
);
|
||||||
|
|
||||||
|
Checkbox::new(hash!())
|
||||||
|
.pos(self.lobby.checkbox_pos)
|
||||||
|
.label("Ready")
|
||||||
|
.size(self.lobby.checkbox_size)
|
||||||
|
.ui(&mut root_ui(), &mut self.lobby.is_ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_game(&self) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_summary_screen(&self) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_chat(&self) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === UPDATING STUFF ==== */
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
self.update_rects();
|
||||||
|
self.update_network();
|
||||||
|
|
||||||
|
match self.game_state {
|
||||||
|
ServerStage::Lobby => self.update_lobby(),
|
||||||
|
ServerStage::Game => todo!(),
|
||||||
|
ServerStage::End => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_network(&mut self) {
|
||||||
|
match self.update_receiver.try_recv() {
|
||||||
|
Ok(msg) => match msg {
|
||||||
|
ServerMessage::GameStart { identity } => {
|
||||||
|
info!("We go identity!");
|
||||||
|
self.identity = Some(identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerMessage::AvailableCaptures { captures } => todo!(),
|
||||||
|
ServerMessage::AvailableMoves { moves } => todo!(),
|
||||||
|
ServerMessage::BroadcastBoardState { board } => todo!(),
|
||||||
|
ServerMessage::BroadcastCurrentTurn { active_player } => todo!(),
|
||||||
|
ServerMessage::BroadCastTextMessage { sender, content } => todo!(),
|
||||||
|
ServerMessage::GameEnd { result } => todo!(),
|
||||||
|
|
||||||
|
_ => {} // ignore things that network client handled by itself
|
||||||
|
},
|
||||||
|
|
||||||
|
Err(Disconnected) => {
|
||||||
|
error!("Connection broken!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(_) => {} // No messages - nothing wrong (why is this even an error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_lobby(&mut self) {
|
||||||
|
self.lobby.checkbox_pos = vec2(
|
||||||
|
self.game_area.w / 2.0 - self.lobby.checkbox_size.x / 2.0,
|
||||||
|
self.game_area.h / 2.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_rects(&mut self) {
|
||||||
|
self.game_area = Rect {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
w: screen_width() * 0.8,
|
||||||
|
h: screen_height(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.chat_area = Rect {
|
||||||
|
x: self.game_area.w,
|
||||||
|
y: 0.0,
|
||||||
|
w: screen_width() * 0.2,
|
||||||
|
h: screen_height(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,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::Connecting(connect_to_server(context.clone()));
|
*state = GuiState::Connecting(connect_to_server());
|
||||||
// TODO Validate url before connecting or something like that
|
// TODO Validate url before connecting or something like that
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use std::sync::mpsc::{self, Receiver};
|
use std::sync::mpsc::{self, Receiver};
|
||||||
|
|
||||||
use crate::{super_advanced_ai::BotDificulty, ui::macroquad::game::GameClient};
|
use crate::{
|
||||||
|
network::client::Client, super_advanced_ai::BotDificulty, ui::macroquad::game::GameClient,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub enum GuiState {
|
pub enum GuiState {
|
||||||
@@ -11,7 +13,7 @@ pub enum GuiState {
|
|||||||
DificultySelection,
|
DificultySelection,
|
||||||
ServerSelection,
|
ServerSelection,
|
||||||
|
|
||||||
Connecting(Receiver<Option<GameClient>>),
|
Connecting(Receiver<Option<Client>>),
|
||||||
|
|
||||||
Settings,
|
Settings,
|
||||||
Game(GameClient),
|
Game(GameClient),
|
||||||
@@ -35,14 +37,13 @@ pub struct GameContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO! Move this
|
// TODO! Move this
|
||||||
pub fn connect_to_server(context: GameContext) -> Receiver<Option<GameClient>> {
|
pub fn connect_to_server() -> Receiver<Option<Client>> {
|
||||||
let (tx, rc) = mpsc::channel::<Option<GameClient>>();
|
let (tx, rc) = mpsc::channel::<Option<Client>>();
|
||||||
let context_clone = context.clone();
|
|
||||||
|
|
||||||
let _ = std::thread::spawn(move || {
|
let _ = std::thread::spawn(move || {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
|
||||||
let client_option = rt.block_on(async { GameClient::new(&context_clone).await });
|
let client_option = rt.block_on(async { Client::new(None).await });
|
||||||
|
|
||||||
let _ = tx.send(client_option);
|
let _ = tx.send(client_option);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user