Add readiness
This commit is contained in:
parent
b01ecbfe13
commit
c594af3bd1
@ -5,10 +5,11 @@
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
||||
font_size = 32
|
||||
|
||||
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field")]
|
||||
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field", "ready_button")]
|
||||
players_list = NodePath("v_box_container/players_list")
|
||||
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
||||
player_listing_prefab = ExtResource("1_o1atq")
|
||||
ready_button = NodePath("ready_button")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
@ -64,3 +65,11 @@ offset_top = -144.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
vertical_alignment = 2
|
||||
|
||||
[node name="ready_button" type="Button" parent="." unique_id=311553419]
|
||||
layout_mode = 0
|
||||
offset_left = 129.0
|
||||
offset_top = 504.0
|
||||
offset_right = 278.0
|
||||
offset_bottom = 555.0
|
||||
text = "Not Ready"
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
[gd_scene format=3 uid="uid://ccd0wj2usx5os"]
|
||||
|
||||
[node name="player_listing" type="PlayerListing" unique_id=772938280 node_paths=PackedStringArray("name_label", "ping_label")]
|
||||
[node name="player_listing" type="PlayerListing" unique_id=772938280 node_paths=PackedStringArray("name_label", "ping_label", "ready_label")]
|
||||
name_label = NodePath("name")
|
||||
ping_label = NodePath("ping")
|
||||
offset_right = 265.0
|
||||
ready_label = NodePath("ready")
|
||||
offset_right = 319.0
|
||||
offset_bottom = 23.0
|
||||
columns = 2
|
||||
columns = 3
|
||||
|
||||
[node name="name" type="Label" parent="." unique_id=635700663]
|
||||
custom_minimum_size = Vector2(200, 0)
|
||||
@ -13,6 +14,12 @@ custom_maximum_size = Vector2(200, -1)
|
||||
layout_mode = 2
|
||||
text = "Name"
|
||||
|
||||
[node name="ready" type="Label" parent="." unique_id=1064828735]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
custom_maximum_size = Vector2(100, -1)
|
||||
layout_mode = 2
|
||||
text = "Ready"
|
||||
|
||||
[node name="ping" type="Label" parent="." unique_id=1935412601]
|
||||
layout_mode = 2
|
||||
text = "(200ms)"
|
||||
|
||||
@ -95,15 +95,16 @@ impl Game {
|
||||
connection_addr: addr,
|
||||
name,
|
||||
ping: 0,
|
||||
ready: false,
|
||||
});
|
||||
self.signals().on_new_player().emit(id);
|
||||
self.run_deferred(move |s| s.signals().on_new_player().emit(id));
|
||||
id
|
||||
}
|
||||
|
||||
pub fn set_players(&mut self, players: Vec<Player>) {
|
||||
self.players = players;
|
||||
for player in self.players.clone() {
|
||||
self.signals().on_new_player().emit(player.id);
|
||||
self.run_deferred(move |s| s.signals().on_new_player().emit(player.id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +118,7 @@ impl Game {
|
||||
|
||||
pub fn remove_player(&mut self, id: u16) {
|
||||
self.players.retain(|p| p.id != id);
|
||||
self.signals().on_player_disconnected().emit(id);
|
||||
self.run_deferred(move |s| s.signals().on_player_disconnected().emit(id));
|
||||
}
|
||||
|
||||
pub fn update_player_nick(&mut self, player_id: u16, nick: String) {
|
||||
@ -133,6 +134,13 @@ impl Game {
|
||||
}
|
||||
self.run_deferred(|s| s.signals().on_players_updated().emit());
|
||||
}
|
||||
|
||||
pub fn update_player_ready(&mut self, player_id: u16, ready: bool) {
|
||||
if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
|
||||
player.ready = ready;
|
||||
}
|
||||
self.run_deferred(|s| s.signals().on_players_updated().emit());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||
@ -141,4 +149,5 @@ pub struct Player {
|
||||
pub connection_addr: SocketAddr,
|
||||
pub name: String,
|
||||
pub ping: u128,
|
||||
pub ready: bool,
|
||||
}
|
||||
|
||||
@ -190,6 +190,12 @@ impl INode for NetworkManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
Package::SetReady(player_id, is_ready) => {
|
||||
if let Some(game) = &mut Game::singleton() {
|
||||
game.bind_mut()
|
||||
.update_player_ready(player_id, is_ready);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
@ -278,6 +284,21 @@ impl INode for NetworkManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
Package::SetReady(_, is_ready) => {
|
||||
if let Some(game) = &mut Game::singleton() {
|
||||
let player = game
|
||||
.bind()
|
||||
.find_player_by_addr(&conn.address)
|
||||
.cloned();
|
||||
if let Some(player) = player {
|
||||
game.bind_mut()
|
||||
.update_player_ready(player.id, is_ready);
|
||||
peer.broadcast_reliable(Package::SetReady(
|
||||
player.id, is_ready,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
@ -319,6 +340,7 @@ impl NetworkManager {
|
||||
"Host".to_owned(),
|
||||
None,
|
||||
);
|
||||
game.bind_mut().update_player_ready(id, true);
|
||||
game.bind_mut().set_self(id);
|
||||
}
|
||||
}
|
||||
@ -393,9 +415,19 @@ pub enum Package {
|
||||
UpdatePings(HashMap<u16, u128>),
|
||||
NewPlayer(Player),
|
||||
PlayerLeft(Player),
|
||||
SetReady(u16, bool),
|
||||
}
|
||||
|
||||
pub enum PeerKind {
|
||||
Client(Peer<Package>, SocketAddr),
|
||||
Server(Peer<Package>, u16),
|
||||
}
|
||||
|
||||
impl PeerKind {
|
||||
pub fn is_host(&self) -> bool {
|
||||
match self {
|
||||
PeerKind::Client(_, _) => false,
|
||||
PeerKind::Server(_, _) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use godot::{
|
||||
classes::{IPanel, Label, Panel, TextEdit, VBoxContainer},
|
||||
classes::{Button, IPanel, Label, Panel, TextEdit, VBoxContainer},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
game_manager::{Game, GameManager},
|
||||
net::network_manager::NetworkManager,
|
||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
||||
ui::player_listing::PlayerListing,
|
||||
};
|
||||
|
||||
@ -18,6 +18,10 @@ pub struct LobbyPanel {
|
||||
name_field: Option<Gd<TextEdit>>,
|
||||
#[export]
|
||||
player_listing_prefab: Option<Gd<PackedScene>>,
|
||||
#[export]
|
||||
ready_button: Option<Gd<Button>>,
|
||||
|
||||
is_ready: bool,
|
||||
|
||||
base: Base<Panel>,
|
||||
}
|
||||
@ -28,15 +32,22 @@ impl IPanel for LobbyPanel {
|
||||
GameManager::singleton()
|
||||
.signals()
|
||||
.on_new_player()
|
||||
.connect_other(self, |s, _| s.update_players_list(true));
|
||||
.connect_other(self, |s, _| s.update_players(true));
|
||||
GameManager::singleton()
|
||||
.signals()
|
||||
.on_player_disconnected()
|
||||
.connect_other(self, |s, _| s.update_players_list(true));
|
||||
.connect_other(self, |s, _| s.update_players(true));
|
||||
GameManager::singleton()
|
||||
.signals()
|
||||
.on_players_updated()
|
||||
.connect_other(self, |s| s.update_players_list(false));
|
||||
.connect_other(self, |s| s.update_players(false));
|
||||
|
||||
if let Some(ready_button) = &self.ready_button {
|
||||
ready_button
|
||||
.signals()
|
||||
.pressed()
|
||||
.connect_other(self, |s| s.on_ready());
|
||||
}
|
||||
|
||||
if let Some(name_field) = &self.name_field {
|
||||
name_field
|
||||
@ -61,12 +72,37 @@ impl IPanel for LobbyPanel {
|
||||
});
|
||||
}
|
||||
|
||||
self.update_players_list(true);
|
||||
self.update_players(true);
|
||||
|
||||
if let Some(peer) = &NetworkManager::singleton().bind().peer
|
||||
&& peer.is_host()
|
||||
{
|
||||
if let Some(button) = &mut self.ready_button {
|
||||
button.set_text("Start Game");
|
||||
button.set_disabled(true);
|
||||
}
|
||||
}
|
||||
self.update_ready_button();
|
||||
}
|
||||
}
|
||||
|
||||
impl LobbyPanel {
|
||||
pub fn update_players_list(&mut self, replace: bool) {
|
||||
fn update_ready_button(&mut self) {
|
||||
if let Some(game) = Game::singleton()
|
||||
&& let Some(peer) = &NetworkManager::singleton().bind().peer
|
||||
{
|
||||
if let PeerKind::Server(_, _) = peer
|
||||
&& let Some(button) = &mut self.ready_button
|
||||
{
|
||||
let all_ready = game.bind().players.iter().all(|p| p.ready);
|
||||
button.set_disabled(!all_ready);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_players(&mut self, replace: bool) {
|
||||
self.update_ready_button();
|
||||
|
||||
if let Some(list) = &mut self.players_list {
|
||||
if replace {
|
||||
for child in list.get_children().iter_shared() {
|
||||
@ -91,4 +127,26 @@ impl LobbyPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_ready(&mut self) {
|
||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||
match peer {
|
||||
PeerKind::Client(peer, socket_addr) => {
|
||||
self.is_ready = !self.is_ready;
|
||||
if let Some(button) = &mut self.ready_button {
|
||||
if self.is_ready {
|
||||
button.set_text("Ready");
|
||||
} else {
|
||||
button.set_text("Not Ready");
|
||||
}
|
||||
}
|
||||
|
||||
peer.send_reliable(socket_addr, Package::SetReady(0, self.is_ready));
|
||||
}
|
||||
PeerKind::Server(_, _) => {
|
||||
godot_print!("Start game!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@ pub struct PlayerListing {
|
||||
pub name_label: Option<Gd<Label>>,
|
||||
#[export]
|
||||
pub ping_label: Option<Gd<Label>>,
|
||||
#[export]
|
||||
pub ready_label: Option<Gd<Label>>,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
|
||||
@ -31,6 +33,14 @@ impl PlayerListing {
|
||||
player_label.set_text(&format!("{} ({})", player.name, player.connection_addr));
|
||||
}
|
||||
|
||||
if let Some(ready_label) = &mut self.ready_label {
|
||||
if player.ready {
|
||||
ready_label.set_text("Ready");
|
||||
} else {
|
||||
ready_label.set_text("Not Ready");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ping_label) = &mut self.ping_label {
|
||||
ping_label.set_text(&format!("({}ms)", player.ping));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user