diff --git a/.vscode/launch.json b/.vscode/launch.json index 323b2e1..424d2c8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "cargo": { "args": ["build"] }, - "args": ["--seed=gargamel"], + "args": ["--seed=gargamel", "--port=25565"], "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", @@ -30,7 +30,7 @@ "cargo": { "args": ["build"] }, - "args": ["--port=25566", "--connect=[::1]:25565"], + "args": ["--connect=[::1]:25565"], "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", diff --git a/src/game/mod.rs b/src/game/mod.rs index 02dda3b..e4efe5d 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -6,6 +6,7 @@ mod runtime; mod seed; mod setup; pub mod state; +mod ui; #[allow(unused_imports)] pub mod prelude { diff --git a/src/game/net.rs b/src/game/net.rs index 2cde3b5..524b376 100644 --- a/src/game/net.rs +++ b/src/game/net.rs @@ -11,7 +11,6 @@ pub fn handle_new_peer( ) { if let Some(seed) = seed { for peer in new_peers { - warn!("Sending seed to peer: {}", peer.uuid); outbound.write(OutboundPacket(Packet::new((*seed).into(), peer.uuid))); } } diff --git a/src/game/plugin.rs b/src/game/plugin.rs index 27242d6..6943b7b 100644 --- a/src/game/plugin.rs +++ b/src/game/plugin.rs @@ -9,8 +9,11 @@ use super::{ net::{handle_deleted_peer, handle_incoming_packets, handle_new_peer}, runtime::{move_camera, move_player, quit, zoom_camera}, seed::Seed, - setup::{check_for_seed, setup_balls, setup_from_seed, setup_player, setup_ui, setup_walls}, + setup::{ + check_for_seed, setup_balls, setup_camera, setup_from_seed, setup_player, setup_walls, + }, state::AppState, + ui::{setup_peer_ui, setup_seed_ui, update_peer_ui, update_peer_ui_timings, update_seed_ui}, }; #[derive(Debug, Clone, Copy)] @@ -56,7 +59,7 @@ impl Plugin for GamePlugin { PhysicsPlugins::default().with_length_unit(50.0), )) .init_state::() - .add_systems(Startup, setup_ui) + .add_systems(Startup, (setup_camera, setup_seed_ui, setup_peer_ui)) .add_systems( OnEnter(AppState::InGame), ( @@ -81,6 +84,9 @@ impl Plugin for GamePlugin { ( ((move_player, move_camera).chain(), zoom_camera) .run_if(in_state(AppState::InGame)), + update_seed_ui, + (update_peer_ui, update_peer_ui_timings) + .run_if(in_state(NetworkState::MultiPlayer)), quit.run_if(input_pressed(KeyCode::KeyQ)), ), ); diff --git a/src/game/setup.rs b/src/game/setup.rs index 0a2f15b..eb4585c 100644 --- a/src/game/setup.rs +++ b/src/game/setup.rs @@ -43,7 +43,7 @@ pub fn setup_from_seed(mut commands: Commands, seed: Res) { } /// I mean, a camera is technically a user interface, I guess -pub fn setup_ui(mut commands: Commands) { +pub fn setup_camera(mut commands: Commands) { commands.spawn((Name::new("Camera"), Camera2d, IsDefaultUiCamera)); } diff --git a/src/game/ui.rs b/src/game/ui.rs new file mode 100644 index 0000000..4abd6d1 --- /dev/null +++ b/src/game/ui.rs @@ -0,0 +1,102 @@ +use bevy::prelude::*; + +use crate::net::prelude::{Peer, PeerReceiveTiming, PeerSendTiming}; + +use super::seed::Seed; + +#[derive(Component, Debug)] +pub struct SeedUI; + +pub fn setup_seed_ui(mut commands: Commands) { + commands + .spawn(( + Text::new("Seed: "), + Node { + position_type: PositionType::Absolute, + bottom: Val::Px(5.0), + left: Val::Px(5.0), + ..default() + }, + )) + .with_child((TextSpan::new(""), SeedUI)); +} + +pub fn update_seed_ui(seed: Option>, text: Query<&mut TextSpan, With>) { + if let Some(value) = seed { + if value.is_changed() { + for mut span in text { + let number: u64 = (*value).into(); + **span = format!("{}", number); + } + } + } +} + +#[derive(Component, Debug)] +pub struct PeerUI; + +pub fn setup_peer_ui(mut commands: Commands) { + commands + .spawn(( + Node { + display: Display::Flex, + position_type: PositionType::Absolute, + top: Val::Px(5.0), + right: Val::Px(5.0), + row_gap: Val::Px(5.0), + flex_direction: FlexDirection::Column, + align_items: AlignItems::FlexEnd, + justify_content: JustifyContent::FlexStart, + ..default() + }, + PeerUI, + )) + .with_children(|builder| { + builder.spawn(Text::new("Peer Recv Send")); + }); +} + +#[derive(Component)] +pub struct PeerID(Entity); + +pub fn update_peer_ui( + ui: Query<(Entity, &Children), With>, + rows: Query<&PeerID>, + added: Query>, + mut removed: RemovedComponents, + mut commands: Commands, +) { + for (table, children) in ui { + for addition in added { + commands + .entity(table) + .with_child((Text::new("---- ---- ----"), PeerID(addition))); + } + for removal in removed.read() { + for child in children { + if let Ok(id) = rows.get(*child) { + if id.0 == removal { + commands.entity(*child).despawn(); + } + } + } + } + } +} + +pub fn update_peer_ui_timings( + rows: Query<(&mut Text, &PeerID)>, + peers: Query<(&Peer, &PeerReceiveTiming, &PeerSendTiming)>, + time: Res