save
Some checks failed
Rust Checks / checks (push) Has been cancelled

This commit is contained in:
CoCo_Sol 2024-03-16 21:39:18 +01:00
parent 64280ab3ff
commit cf08767ac4
10 changed files with 176 additions and 14 deletions

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"rust-analyzer.showUnlinkedFileNotification": false
}

11
Cargo.lock generated
View file

@ -1314,10 +1314,13 @@ dependencies = [
name = "border-wars" name = "border-wars"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bevnet",
"bevy", "bevy",
"bevy_egui", "bevy_egui",
"noise", "noise",
"paste", "paste",
"serde",
"uuid",
] ]
[[package]] [[package]]
@ -3805,18 +3808,18 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.196" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.196" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -15,3 +15,6 @@ bevy = "0.12.1"
bevy_egui = "0.24.0" bevy_egui = "0.24.0"
noise = "0.8.2" noise = "0.8.2"
paste = "1.0.14" paste = "1.0.14"
bevnet = { path = "../bevnet" }
uuid = "1.7.0"
serde = "1.0.197"

View file

@ -0,0 +1,37 @@
//! All the code related to the connection to an host.
use std::collections::HashMap;
use bevnet::NetworkAppExt;
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// TODO
#[derive(Resource, Default, Deserialize, Serialize, Clone)]
pub struct AllPlayers(pub HashMap<String, Uuid>);
/// The plugin that manages the connection to the host.
pub struct ConnectionPlugin;
impl Plugin for ConnectionPlugin {
fn build(&self, app: &mut App) {
app.add_network_event::<RequestConnection>()
.add_network_event::<UpdatePlayers>()
.init_resource::<AllPlayers>();
}
}
#[derive(Event, Deserialize, Serialize)]
/// The message sent by the client to the server to request a connection.
pub struct RequestConnection {
/// The name of the player.
pub name: String,
}
#[derive(Event, Deserialize, Serialize)]
/// The message sent by the server to all clients when a new player joins.
pub struct UpdatePlayers {
/// All players in the game.
pub players: AllPlayers,
}

View file

@ -3,6 +3,7 @@
use bevy::prelude::*; use bevy::prelude::*;
pub mod camera; pub mod camera;
pub mod connection;
pub mod map; pub mod map;
pub mod responsive_scale; pub mod responsive_scale;
pub mod scenes; pub mod scenes;
@ -14,9 +15,16 @@ pub enum CurrentScene {
#[default] #[default]
Menu, Menu,
/// When we are in the lobby waiting for players to join the game. /// When you are the host in the lobby waiting for players to join the game.
Lobby, Lobby,
/// When you are the player waiting for the host to start.
JoinMenu,
/// When we play this wonderful game. /// When we play this wonderful game.
Game, Game,
} }
/// The name of the player.
#[derive(Resource, Clone, Default)]
pub struct PlayerName(pub String);

View file

@ -1,7 +1,9 @@
//! The main entry point of the game. //! The main entry point of the game.
use bevnet::NetworkPlugin;
use bevy::prelude::*; use bevy::prelude::*;
use border_wars::camera::CameraPlugin; use border_wars::camera::CameraPlugin;
use border_wars::connection::ConnectionPlugin;
use border_wars::map::click_tile::TilesClickable; use border_wars::map::click_tile::TilesClickable;
use border_wars::map::renderer::RendererPlugin; use border_wars::map::renderer::RendererPlugin;
use border_wars::scenes::ScenesPlugin; use border_wars::scenes::ScenesPlugin;
@ -13,5 +15,7 @@ fn main() {
.add_plugins(RendererPlugin) .add_plugins(RendererPlugin)
.add_plugins(CameraPlugin) .add_plugins(CameraPlugin)
.add_plugins(TilesClickable) .add_plugins(TilesClickable)
.add_plugins(NetworkPlugin::new("relay.cocosol.fr".to_string()))
.add_plugins(ConnectionPlugin)
.run(); .run();
} }

View file

@ -0,0 +1,52 @@
//! The lobby of the game.
use std::collections::HashMap;
use bevnet::{Connection, Receive, SendTo, Uuid};
use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts};
use crate::connection::{AllPlayers, RequestConnection, UpdatePlayers};
use crate::{CurrentScene, PlayerName};
/// The plugin for the lobby.
pub struct JoinMenuPlugin;
impl Plugin for JoinMenuPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(menu_ui, update_players).run_if(in_state(CurrentScene::JoinMenu)),
);
}
}
/// Display the UI of the lobby.
fn menu_ui(mut ctx: EguiContexts, all_players: Res<AllPlayers>) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars");
ui.separator();
for player in all_players.0.values() {
ui.horizontal(|ui| {
ui.label(player.to_string());
});
}
});
}
fn update_players(
mut event_reader: EventReader<Receive<UpdatePlayers>>,
mut all_players: ResMut<AllPlayers>,
name: Res<PlayerName>,
mut next_scene: ResMut<NextState<CurrentScene>>,
) {
for event in event_reader.read() {
println!(
"{:?}",
event.1.players.0.values().into_iter().collect::<Vec<_>>()
);
*all_players = event.1.players.clone();
}
}

View file

@ -1,21 +1,33 @@
//! The lobby of the game. //! The lobby of the game.
use std::collections::HashMap;
use bevnet::{Connection, Receive, SendTo, Uuid};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts}; use bevy_egui::{egui, EguiContexts};
use crate::CurrentScene; use crate::connection::{AllPlayers, RequestConnection, UpdatePlayers};
use crate::{CurrentScene, PlayerName};
/// The plugin for the lobby. /// The plugin for the lobby.
pub struct LobbyPlugin; pub struct LobbyPlugin;
impl Plugin for LobbyPlugin { impl Plugin for LobbyPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Update, lobby_ui.run_if(in_state(CurrentScene::Lobby))); app.add_systems(Update, lobby_ui.run_if(in_state(CurrentScene::Lobby)))
.add_systems(
Update,
handle_connection.run_if(in_state(CurrentScene::Lobby)),
);
} }
} }
/// Display the UI of the lobby. /// Display the UI of the lobby.
fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene>>) { fn lobby_ui(
mut ctx: EguiContexts,
mut next_scene: ResMut<NextState<CurrentScene>>,
connection_string: Res<Connection>,
) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars"); ui.heading("Border Wars");
@ -25,7 +37,7 @@ fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Game ID: "); ui.label("Game ID: ");
// TODO : get the game ID and display it. // TODO : get the game ID and display it.
ui.label("connection_string"); ui.text_edit_singleline(&mut connection_string.identifier().unwrap().to_string());
}); });
ui.separator(); ui.separator();
@ -36,3 +48,25 @@ fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene
} }
}); });
} }
fn handle_connection(
mut event_reader: EventReader<Receive<RequestConnection>>,
mut event_writer: EventWriter<SendTo<UpdatePlayers>>,
mut all_players: ResMut<AllPlayers>,
) {
for event in event_reader.read() {
if !all_players.0.contains_key(&event.1.name) {
all_players.0.insert(event.1.name.clone(), event.0);
println!("yes");
}
for player in all_players.0.values() {
println!("{:?}", player);
event_writer.send(SendTo(
*player,
UpdatePlayers {
players: all_players.clone(),
},
));
}
}
}

View file

@ -1,23 +1,30 @@
//! The main menu of the game. //! The main menu of the game.
use bevnet::{Connection, SendTo, Uuid};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts}; use bevy_egui::{egui, EguiContexts};
use crate::CurrentScene; use crate::connection::RequestConnection;
use crate::{CurrentScene, PlayerName};
type Name = String;
/// The plugin for the menu. /// The plugin for the menu.
pub struct MenuPlugin; pub struct MenuPlugin;
impl Plugin for MenuPlugin { impl Plugin for MenuPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Update, menu_ui.run_if(in_state(CurrentScene::Menu))); app.init_resource::<PlayerName>()
.add_systems(Update, menu_ui.run_if(in_state(CurrentScene::Menu)));
} }
} }
/// Display the UI of the menu to host a game or join one. /// Display the UI of the menu to host a game or join one.
fn menu_ui( fn menu_ui(
mut ctx: EguiContexts, mut ctx: EguiContexts,
mut connection_string: Local<String>, mut connection_string: Local<String>,
mut name: ResMut<PlayerName>,
mut next_scene: ResMut<NextState<CurrentScene>>, mut next_scene: ResMut<NextState<CurrentScene>>,
mut event: EventWriter<SendTo<RequestConnection>>,
) { ) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars"); ui.heading("Border Wars");
@ -26,12 +33,22 @@ fn menu_ui(
ui.label("Connect to an existing game:"); ui.label("Connect to an existing game:");
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("name: ");
ui.text_edit_singleline(&mut name.0);
ui.separator();
ui.label("Game ID: "); ui.label("Game ID: ");
ui.text_edit_singleline(&mut *connection_string); ui.text_edit_singleline(&mut *connection_string);
if ui.button("Join").clicked() { if ui.button("Join").clicked() {
next_scene.set(CurrentScene::Game); next_scene.set(CurrentScene::JoinMenu);
// TODO: connect to the game
event.send(SendTo {
0: Uuid::parse_str(&connection_string).unwrap(),
1: RequestConnection {
name: (*name.0).to_string(),
},
})
} }
}); });
@ -39,7 +56,6 @@ fn menu_ui(
if ui.button("Create new game").clicked() { if ui.button("Create new game").clicked() {
next_scene.set(CurrentScene::Lobby); next_scene.set(CurrentScene::Lobby);
// TODO: create a new game
} }
}); });
} }

View file

@ -5,6 +5,7 @@ use bevy_egui::EguiPlugin;
use crate::{responsive_scale, CurrentScene}; use crate::{responsive_scale, CurrentScene};
pub mod join_menu;
pub mod lobby; pub mod lobby;
pub mod menu; pub mod menu;
@ -17,6 +18,7 @@ impl Plugin for ScenesPlugin {
.add_state::<CurrentScene>() .add_state::<CurrentScene>()
.add_plugins(menu::MenuPlugin) .add_plugins(menu::MenuPlugin)
.add_plugins(lobby::LobbyPlugin) .add_plugins(lobby::LobbyPlugin)
.add_plugins(join_menu::JoinMenuPlugin)
.add_plugins(responsive_scale::ResponsiveScalingPlugin); .add_plugins(responsive_scale::ResponsiveScalingPlugin);
} }
} }