Add readiness
This commit is contained in:
parent
b01ecbfe13
commit
c594af3bd1
@ -5,10 +5,11 @@
|
|||||||
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
||||||
font_size = 32
|
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")
|
players_list = NodePath("v_box_container/players_list")
|
||||||
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
||||||
player_listing_prefab = ExtResource("1_o1atq")
|
player_listing_prefab = ExtResource("1_o1atq")
|
||||||
|
ready_button = NodePath("ready_button")
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -64,3 +65,11 @@ offset_top = -144.0
|
|||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
vertical_alignment = 2
|
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"]
|
[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")
|
name_label = NodePath("name")
|
||||||
ping_label = NodePath("ping")
|
ping_label = NodePath("ping")
|
||||||
offset_right = 265.0
|
ready_label = NodePath("ready")
|
||||||
|
offset_right = 319.0
|
||||||
offset_bottom = 23.0
|
offset_bottom = 23.0
|
||||||
columns = 2
|
columns = 3
|
||||||
|
|
||||||
[node name="name" type="Label" parent="." unique_id=635700663]
|
[node name="name" type="Label" parent="." unique_id=635700663]
|
||||||
custom_minimum_size = Vector2(200, 0)
|
custom_minimum_size = Vector2(200, 0)
|
||||||
@ -13,6 +14,12 @@ custom_maximum_size = Vector2(200, -1)
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Name"
|
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]
|
[node name="ping" type="Label" parent="." unique_id=1935412601]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "(200ms)"
|
text = "(200ms)"
|
||||||
|
|||||||
@ -95,15 +95,16 @@ impl Game {
|
|||||||
connection_addr: addr,
|
connection_addr: addr,
|
||||||
name,
|
name,
|
||||||
ping: 0,
|
ping: 0,
|
||||||
|
ready: false,
|
||||||
});
|
});
|
||||||
self.signals().on_new_player().emit(id);
|
self.run_deferred(move |s| s.signals().on_new_player().emit(id));
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_players(&mut self, players: Vec<Player>) {
|
pub fn set_players(&mut self, players: Vec<Player>) {
|
||||||
self.players = players;
|
self.players = players;
|
||||||
for player in self.players.clone() {
|
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) {
|
pub fn remove_player(&mut self, id: u16) {
|
||||||
self.players.retain(|p| p.id != id);
|
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) {
|
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());
|
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)]
|
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||||
@ -141,4 +149,5 @@ pub struct Player {
|
|||||||
pub connection_addr: SocketAddr,
|
pub connection_addr: SocketAddr,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub ping: u128,
|
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(),
|
"Host".to_owned(),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
game.bind_mut().update_player_ready(id, true);
|
||||||
game.bind_mut().set_self(id);
|
game.bind_mut().set_self(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,9 +415,19 @@ pub enum Package {
|
|||||||
UpdatePings(HashMap<u16, u128>),
|
UpdatePings(HashMap<u16, u128>),
|
||||||
NewPlayer(Player),
|
NewPlayer(Player),
|
||||||
PlayerLeft(Player),
|
PlayerLeft(Player),
|
||||||
|
SetReady(u16, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum PeerKind {
|
pub enum PeerKind {
|
||||||
Client(Peer<Package>, SocketAddr),
|
Client(Peer<Package>, SocketAddr),
|
||||||
Server(Peer<Package>, u16),
|
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::{
|
use godot::{
|
||||||
classes::{IPanel, Label, Panel, TextEdit, VBoxContainer},
|
classes::{Button, IPanel, Label, Panel, TextEdit, VBoxContainer},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game_manager::{Game, GameManager},
|
game_manager::{Game, GameManager},
|
||||||
net::network_manager::NetworkManager,
|
net::network_manager::{NetworkManager, Package, PeerKind},
|
||||||
ui::player_listing::PlayerListing,
|
ui::player_listing::PlayerListing,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,6 +18,10 @@ pub struct LobbyPanel {
|
|||||||
name_field: Option<Gd<TextEdit>>,
|
name_field: Option<Gd<TextEdit>>,
|
||||||
#[export]
|
#[export]
|
||||||
player_listing_prefab: Option<Gd<PackedScene>>,
|
player_listing_prefab: Option<Gd<PackedScene>>,
|
||||||
|
#[export]
|
||||||
|
ready_button: Option<Gd<Button>>,
|
||||||
|
|
||||||
|
is_ready: bool,
|
||||||
|
|
||||||
base: Base<Panel>,
|
base: Base<Panel>,
|
||||||
}
|
}
|
||||||
@ -28,15 +32,22 @@ impl IPanel for LobbyPanel {
|
|||||||
GameManager::singleton()
|
GameManager::singleton()
|
||||||
.signals()
|
.signals()
|
||||||
.on_new_player()
|
.on_new_player()
|
||||||
.connect_other(self, |s, _| s.update_players_list(true));
|
.connect_other(self, |s, _| s.update_players(true));
|
||||||
GameManager::singleton()
|
GameManager::singleton()
|
||||||
.signals()
|
.signals()
|
||||||
.on_player_disconnected()
|
.on_player_disconnected()
|
||||||
.connect_other(self, |s, _| s.update_players_list(true));
|
.connect_other(self, |s, _| s.update_players(true));
|
||||||
GameManager::singleton()
|
GameManager::singleton()
|
||||||
.signals()
|
.signals()
|
||||||
.on_players_updated()
|
.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 {
|
if let Some(name_field) = &self.name_field {
|
||||||
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 {
|
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 let Some(list) = &mut self.players_list {
|
||||||
if replace {
|
if replace {
|
||||||
for child in list.get_children().iter_shared() {
|
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>>,
|
pub name_label: Option<Gd<Label>>,
|
||||||
#[export]
|
#[export]
|
||||||
pub ping_label: Option<Gd<Label>>,
|
pub ping_label: Option<Gd<Label>>,
|
||||||
|
#[export]
|
||||||
|
pub ready_label: Option<Gd<Label>>,
|
||||||
|
|
||||||
pub player_id: Option<u16>,
|
pub player_id: Option<u16>,
|
||||||
|
|
||||||
@ -31,6 +33,14 @@ impl PlayerListing {
|
|||||||
player_label.set_text(&format!("{} ({})", player.name, player.connection_addr));
|
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 {
|
if let Some(ping_label) = &mut self.ping_label {
|
||||||
ping_label.set_text(&format!("({}ms)", player.ping));
|
ping_label.set_text(&format!("({}ms)", player.ping));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user