1
Fork 0
mirror of https://github.com/Steffo99/nanogolf.git synced 2024-11-21 23:54:21 +00:00

Get lobby and player list working

This commit is contained in:
Steffo 2024-02-28 06:30:45 +01:00
parent d54b981e25
commit ada7d71855
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
19 changed files with 209 additions and 103 deletions

View file

@ -2,6 +2,15 @@ extends Node
class_name Game class_name Game
signal trackers_changed(trackers: Dictionary)
func _on_trackers_changed(trackers: Dictionary):
trackers_changed.emit(trackers)
@onready var mp_tracker: MultiplePlayersTracker = $"MultiplePlayersTracker"
# This cannot be called in _ready because the multiplayer node is set *after* adding the node to the tree. # This cannot be called in _ready because the multiplayer node is set *after* adding the node to the tree.
func init_signals(): func init_signals():
print("[Game] Initializing signals...") print("[Game] Initializing signals...")
@ -12,17 +21,43 @@ func init_signals():
multiplayer.peer_disconnected.connect(_on_peer_disconnected) multiplayer.peer_disconnected.connect(_on_peer_disconnected)
var local_player_name: String = "Player"
var local_player_color: Color = Color.WHITE
func init_identity(player_name: String, player_color: Color):
local_player_name = player_name
local_player_color = player_color
func _on_connected_to_server(): func _on_connected_to_server():
print("{", multiplayer.multiplayer_peer.get_unique_id(), "} Connected to server!") Log.peer(self, "Connected to server!")
func _on_server_disconnected(): func _on_server_disconnected():
print("{", multiplayer.multiplayer_peer.get_unique_id(), "} Server disconnected...") Log.peer(self, "Server disconnected...")
func _on_connection_failed(): func _on_connection_failed():
print("{", multiplayer.multiplayer_peer.get_unique_id(), "} Connection failed...") Log.peer(self, "Connection failed...")
func _on_peer_connected(peer_id: int): func _on_peer_connected(peer_id: int):
print("{", multiplayer.multiplayer_peer.get_unique_id(), "} Peer connected: ", peer_id) Log.peer(self, "Peer connected: " + str(peer_id))
if multiplayer.is_server():
assert(peer_id != 1, "This is a server, but the remote peer_id is 1.")
Log.peer(self, "Initializing tracker for: " + str(peer_id))
mp_tracker.spawn(peer_id)
func _on_peer_disconnected(peer_id: int): func _on_peer_disconnected(peer_id: int):
print("{", multiplayer.multiplayer_peer.get_unique_id(), "} Peer disconnected: ", peer_id) Log.peer(self, "Peer disconnected: " + str(peer_id))
if multiplayer.is_server():
assert(peer_id != 1, "This is a server, but the remote peer_id is 1.")
Log.peer(self, "Deinitializing tracker for: " + str(peer_id))
mp_tracker.mark_disconnected.rpc(peer_id)
func _on_single_player_tracker_spawned(spawned_tracker: SinglePlayerTracker) -> void:
# If we spawned ourselves, set our own identity
if spawned_tracker.get_multiplayer_authority() == multiplayer.multiplayer_peer.get_unique_id():
spawned_tracker.update_identity.rpc(local_player_name, local_player_color)
# If another player spawned, and they connected before us, send them our identity
else:
var self_tracker = mp_tracker.find(multiplayer.multiplayer_peer.get_unique_id())
if self_tracker != null:
self_tracker.notify_identity(spawned_tracker.get_multiplayer_authority())

View file

@ -7,3 +7,6 @@
script = ExtResource("1_cdtng") script = ExtResource("1_cdtng")
[node name="MultiplePlayersTracker" parent="." instance=ExtResource("2_f2gy2")] [node name="MultiplePlayersTracker" parent="." instance=ExtResource("2_f2gy2")]
[connection signal="spawned" from="MultiplePlayersTracker" to="." method="_on_single_player_tracker_spawned"]
[connection signal="trackers_changed" from="MultiplePlayersTracker" to="." method="_on_trackers_changed"]

9
scenes/lobby_menu.gd Normal file
View file

@ -0,0 +1,9 @@
extends Control
class_name LobbyMenu
@onready var players_list: PlayersList = $"Layout/PlayersList"
func _on_trackers_changed(trackers: Dictionary):
players_list._on_trackers_changed(trackers)

43
scenes/lobby_menu.tscn Normal file
View file

@ -0,0 +1,43 @@
[gd_scene load_steps=3 format=3 uid="uid://cxpn0653ssa53"]
[ext_resource type="Script" path="res://scenes/lobby_menu.gd" id="1_egicy"]
[ext_resource type="PackedScene" uid="uid://cpyclix18d3it" path="res://scenes/players_list.tscn" id="2_o2f1d"]
[node name="LobbyMenu" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_egicy")
[node name="Layout" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Title" type="RichTextLabel" parent="Layout"]
layout_mode = 2
bbcode_enabled = true
text = "[center][font_size=32px][b]Nanogolf[/b][/font_size]
Stanza multigiocatore[/center]"
fit_content = true
[node name="Padding" type="Control" parent="Layout"]
custom_minimum_size = Vector2(0, 16)
layout_mode = 2
[node name="PlayersList" parent="Layout" instance=ExtResource("2_o2f1d")]
layout_mode = 2
[node name="Padding2" type="Control" parent="Layout"]
custom_minimum_size = Vector2(0, 16)
layout_mode = 2
[node name="Button" type="Button" parent="Layout"]
layout_mode = 2
text = "Avvia partita"

View file

@ -12,6 +12,8 @@ const game_scene: PackedScene = preload("res://scenes/game.tscn")
var server_game_instance: Game = null var server_game_instance: Game = null
var client_game_instance: Game = null var client_game_instance: Game = null
const lobby_menu_scene: PackedScene = preload("res://scenes/lobby_menu.tscn")
var lobby_menu_instance: LobbyMenu = null
func init_main_menu(): func init_main_menu():
main_menu_instance = main_menu_scene.instantiate() main_menu_instance = main_menu_scene.instantiate()
@ -27,8 +29,6 @@ func init_server_game(server_port: int):
server_game_instance.name = "Server" server_game_instance.name = "Server"
add_child(server_game_instance, true) add_child(server_game_instance, true)
server_game_instance.init_signals()
print("[Main] Creating server at: *:", server_port) print("[Main] Creating server at: *:", server_port)
var smp: SceneMultiplayer = SceneMultiplayer.new() var smp: SceneMultiplayer = SceneMultiplayer.new()
var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
@ -38,6 +38,7 @@ func init_server_game(server_port: int):
return return
scene_tree.set_multiplayer(smp, ^"/root/Main/Server") scene_tree.set_multiplayer(smp, ^"/root/Main/Server")
server_game_instance.init_signals()
smp.set_multiplayer_peer(peer) smp.set_multiplayer_peer(peer)
func deinit_server_game(): func deinit_server_game():
@ -52,8 +53,6 @@ func init_client_game(player_name: String, player_color: Color, server_address:
client_game_instance.name = "Client" client_game_instance.name = "Client"
add_child(client_game_instance, true) add_child(client_game_instance, true)
client_game_instance.init_signals()
print("[Main] Creating client connecting to: ", server_address, ":", server_port) print("[Main] Creating client connecting to: ", server_address, ":", server_port)
var smp = SceneMultiplayer.new() var smp = SceneMultiplayer.new()
var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
@ -63,6 +62,8 @@ func init_client_game(player_name: String, player_color: Color, server_address:
return return
scene_tree.set_multiplayer(smp, ^"/root/Main/Client") scene_tree.set_multiplayer(smp, ^"/root/Main/Client")
client_game_instance.init_signals()
client_game_instance.init_identity(player_name, player_color)
smp.set_multiplayer_peer(peer) smp.set_multiplayer_peer(peer)
func deinit_client_game(): func deinit_client_game():
@ -72,6 +73,12 @@ func deinit_client_game():
scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Client") scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Client")
client_game_instance.queue_free() client_game_instance.queue_free()
func init_lobby_menu():
lobby_menu_instance = lobby_menu_scene.instantiate()
interface_instance.add_child(lobby_menu_instance)
func deinit_lobby_menu():
lobby_menu_instance.queue_free()
func _ready(): func _ready():
init_main_menu() init_main_menu()
@ -79,8 +86,12 @@ func _ready():
func _on_hosting_confirmed(player_name: String, player_color: Color, server_port: int): func _on_hosting_confirmed(player_name: String, player_color: Color, server_port: int):
deinit_main_menu() deinit_main_menu()
init_server_game(server_port) init_server_game(server_port)
# init_client_game(player_name, player_color, "127.0.0.1", server_port) init_client_game(player_name, player_color, "127.0.0.1", server_port)
init_lobby_menu()
client_game_instance.trackers_changed.connect(lobby_menu_instance._on_trackers_changed)
func _on_connecting_confirmed(player_name: String, player_color: Color, server_address: String, server_port: int): func _on_connecting_confirmed(player_name: String, player_color: Color, server_address: String, server_port: int):
deinit_main_menu() deinit_main_menu()
init_client_game(player_name, player_color, server_address, server_port) init_client_game(player_name, player_color, server_address, server_port)
init_lobby_menu()
client_game_instance.trackers_changed.connect(lobby_menu_instance._on_trackers_changed)

View file

@ -3,32 +3,36 @@ class_name MultiplePlayersTracker
# Requires the peer_id as data for the spawn function. # Requires the peer_id as data for the spawn function.
signal trackers_changed(trackers: Dictionary)
func get_tracker_by_peer(peer_id: int) -> SinglePlayerTracker: func emit_trackers_changed():
for child in find_children("", "SinglePlayerTracker", false): trackers_changed.emit(trackers_by_peer_id)
if child.peer_id == peer_id:
return child
return null
func init_tracker(peer_id: int) -> SinglePlayerTracker:
var existing_tracker: SinglePlayerTracker = get_tracker_by_peer(peer_id)
if existing_tracker != null:
return existing_tracker
var single_tracker_instance = spawn(peer_id)
return single_tracker_instance
var trackers_by_peer_id: Dictionary = {}
func find(peer_id: int) -> SinglePlayerTracker:
return trackers_by_peer_id.get(peer_id)
@rpc("authority", "call_local", "reliable")
func mark_disconnected(peer_id: int):
var single_tracker_instance = find(peer_id)
single_tracker_instance.set_multiplayer_authority(1)
single_tracker_instance.peer_connected = false
emit_trackers_changed()
func _ready(): func _ready():
spawn_function = _spawn_tracker spawn_function = _spawn_tracker
func _spawn_tracker(data: Variant) -> Node: func _spawn_tracker(peer_id: int) -> Node:
print("Spawning ", data)
var single_tracker_scene: PackedScene = load(get_spawnable_scene(0)) var single_tracker_scene: PackedScene = load(get_spawnable_scene(0))
var single_tracker_instance: SinglePlayerTracker = single_tracker_scene.instantiate() var single_tracker_instance: SinglePlayerTracker = single_tracker_scene.instantiate()
single_tracker_instance.peer_id = data single_tracker_instance.set_multiplayer_authority(peer_id)
single_tracker_instance.identity_updated.connect(_on_tracker_identity_updated)
trackers_by_peer_id[peer_id] = single_tracker_instance
emit_trackers_changed()
return single_tracker_instance return single_tracker_instance
func _on_tracker_identity_updated(_player_name: String, _player_color: Color):
func _process(delta): emit_trackers_changed()
if multiplayer.is_server() and Input.is_action_just_pressed("ui_accept"):
spawn(1)

View file

@ -4,18 +4,12 @@ class_name PlayerColorPicker
signal color_confirmed(selected_color: Color) signal color_confirmed(selected_color: Color)
var selected_color: Color = Color.WHITE: @onready var color_picker: ColorPicker = $"Layout/ColorPicker"
get:
return selected_color
set(value):
selected_color = value
preview_texture.modulate = value
@onready var preview_texture: TextureRect = $"Layout/PreviewContainer/PreviewTexture" @onready var preview_texture: TextureRect = $"Layout/PreviewContainer/PreviewTexture"
func _on_color_picker_color_changed(color: Color): func _on_color_picker_color_changed(color: Color):
selected_color = color preview_texture.modulate = color
func _on_button_pressed(): func _on_button_pressed():
color_confirmed.emit(selected_color) color_confirmed.emit(color_picker.color)

View file

@ -21,6 +21,7 @@ fit_content = true
[node name="ColorPicker" type="ColorPicker" parent="Layout"] [node name="ColorPicker" type="ColorPicker" parent="Layout"]
layout_mode = 2 layout_mode = 2
color = Color(1, 0.996078, 0, 1)
picker_shape = 1 picker_shape = 1
can_add_swatches = false can_add_swatches = false
sampler_visible = false sampler_visible = false

8
scenes/player_label.gd Normal file
View file

@ -0,0 +1,8 @@
extends Label
class_name PlayerLabel
func update_from_tracker(tracker: SinglePlayerTracker):
text = tracker.player_name
add_theme_color_override("font_color", tracker.player_color)
modulate.a = 1.0 if tracker.peer_connected else 0.3

7
scenes/player_label.tscn Normal file
View file

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://dbj7jomrsn41h"]
[ext_resource type="Script" path="res://scenes/player_label.gd" id="1_p6mii"]
[node name="PlayerLabel" type="Label"]
text = "Player"
script = ExtResource("1_p6mii")

View file

@ -4,23 +4,11 @@ class_name PlayerNameInput
signal name_confirmed(selected_name: String) signal name_confirmed(selected_name: String)
var selected_name: String = "":
get:
return selected_name
set(value):
selected_name = value
@onready var line_edit: LineEdit = $"Layout/LineEdit" @onready var line_edit: LineEdit = $"Layout/LineEdit"
func _on_line_edit_text_changed(new_text: String):
selected_name = new_text
func _on_button_pressed(): func _on_button_pressed():
name_confirmed.emit(selected_name) name_confirmed.emit(line_edit.text)
func _on_line_edit_text_submitted(new_text: String): func _on_line_edit_text_submitted(new_text: String):
selected_name = new_text name_confirmed.emit(line_edit.text)
name_confirmed.emit(selected_name)

View file

@ -18,6 +18,7 @@ fit_content = true
[node name="LineEdit" type="LineEdit" parent="Layout"] [node name="LineEdit" type="LineEdit" parent="Layout"]
layout_mode = 2 layout_mode = 2
text = "Steffo"
placeholder_text = "Garasino Garasotti" placeholder_text = "Garasino Garasotti"
[node name="PaddingEnd" type="Control" parent="Layout"] [node name="PaddingEnd" type="Control" parent="Layout"]

16
scenes/players_list.gd Normal file
View file

@ -0,0 +1,16 @@
extends PanelContainer
class_name PlayersList
@onready var layout = $"Scrollable/Layout"
const player_label_scene = preload("res://scenes/player_label.tscn")
func _on_trackers_changed(trackers: Dictionary):
for child in layout.get_children():
child.queue_free()
for tracker in trackers.values():
var player_label_instance = player_label_scene.instantiate()
player_label_instance.update_from_tracker(tracker)
layout.add_child(player_label_instance)

14
scenes/players_list.tscn Normal file
View file

@ -0,0 +1,14 @@
[gd_scene load_steps=2 format=3 uid="uid://cpyclix18d3it"]
[ext_resource type="Script" path="res://scenes/players_list.gd" id="1_45xu7"]
[node name="PlayersList" type="PanelContainer"]
size_flags_vertical = 3
script = ExtResource("1_45xu7")
[node name="Scrollable" type="ScrollContainer" parent="."]
layout_mode = 2
[node name="Layout" type="VBoxContainer" parent="Scrollable"]
layout_mode = 2
size_flags_vertical = 3

View file

@ -7,21 +7,11 @@ class_name ServerOptionsMenu
signal hosting_confirmed(port: int) signal hosting_confirmed(port: int)
signal connecting_confirmed(address: String, port: int) signal connecting_confirmed(address: String, port: int)
var selected_address: String = "":
get:
return selected_address
set(value):
selected_address = value
@onready var line_edit: LineEdit = $"Layout/LineEdit" @onready var line_edit: LineEdit = $"Layout/LineEdit"
func _on_line_edit_text_changed(new_text):
selected_address = new_text
func _on_host_button_pressed(): func _on_host_button_pressed():
hosting_confirmed.emit(port) hosting_confirmed.emit(port)
func _on_connect_button_pressed(): func _on_connect_button_pressed():
connecting_confirmed.emit(selected_address, port) connecting_confirmed.emit(line_edit.text, port)

View file

@ -35,6 +35,7 @@ horizontal_alignment = 1
[node name="LineEdit" type="LineEdit" parent="Layout"] [node name="LineEdit" type="LineEdit" parent="Layout"]
layout_mode = 2 layout_mode = 2
text = "127.0.0.1"
placeholder_text = "127.0.0.1" placeholder_text = "127.0.0.1"
[node name="ConnectButton" type="Button" parent="Layout"] [node name="ConnectButton" type="Button" parent="Layout"]
@ -42,5 +43,4 @@ layout_mode = 2
text = "Connettiti al server" text = "Connettiti al server"
[connection signal="pressed" from="Layout/HostButton" to="." method="_on_host_button_pressed"] [connection signal="pressed" from="Layout/HostButton" to="." method="_on_host_button_pressed"]
[connection signal="text_changed" from="Layout/LineEdit" to="." method="_on_line_edit_text_changed"]
[connection signal="pressed" from="Layout/ConnectButton" to="." method="_on_connect_button_pressed"] [connection signal="pressed" from="Layout/ConnectButton" to="." method="_on_connect_button_pressed"]

View file

@ -1,28 +1,12 @@
extends MultiplayerSynchronizer extends Node
class_name SinglePlayerTracker class_name SinglePlayerTracker
## Emitted when the peer represented by this object connects.
signal peer_has_connected
## Emitted when the peer represented by this object connects. signal identity_updated(player_name: String, player_color: Color)
signal peer_has_disconnected
## The peer ID that this object represents.
var peer_id: int = 0
## Whether the peer is connected or not. ## Whether the peer is connected or not.
var peer_connected: bool = false: var peer_connected: bool = true
get:
return peer_connected
set(value):
var pvalue = peer_connected
peer_connected = value
if value != pvalue:
if value:
peer_has_connected.emit()
else:
peer_has_disconnected.emit()
## The player's name. ## The player's name.
var player_name: String = "Player" var player_name: String = "Player"
@ -32,3 +16,14 @@ var player_color: Color = Color.WHITE
## This player's score, with an item per hole played. ## This player's score, with an item per hole played.
var strokes_per_hole: Array[int] = [] var strokes_per_hole: Array[int] = []
@rpc("authority", "call_local", "reliable")
func update_identity(new_player_name: String, new_player_color: Color):
player_name = new_player_name
player_color = new_player_color
identity_updated.emit(player_name, player_color)
func notify_identity(peer_id: int):
Log.peer(self, "Notifying of our identity: " + str(peer_id))
update_identity.rpc_id(peer_id, player_name, player_color)

View file

@ -1,25 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://drccgvtcng3ju"] [gd_scene load_steps=2 format=3 uid="uid://drccgvtcng3ju"]
[ext_resource type="Script" path="res://scenes/single_player_tracker.gd" id="1_jwlkv"] [ext_resource type="Script" path="res://scenes/single_player_tracker.gd" id="1_jwlkv"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_aosye"] [node name="SinglePlayerTracker" type="Node"]
properties/0/path = NodePath(".:peer_id")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath(".:peer_connected")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath(".:player_name")
properties/2/spawn = true
properties/2/replication_mode = 2
properties/3/path = NodePath(".:player_color")
properties/3/spawn = true
properties/3/replication_mode = 2
properties/4/path = NodePath(".:strokes_per_hole")
properties/4/spawn = true
properties/4/replication_mode = 2
[node name="SinglePlayerTracker" type="MultiplayerSynchronizer"]
root_path = NodePath(".")
replication_config = SubResource("SceneReplicationConfig_aosye")
script = ExtResource("1_jwlkv") script = ExtResource("1_jwlkv")

6
utils/log.gd Normal file
View file

@ -0,0 +1,6 @@
extends Node
class_name Log
static func peer(this: Node, string: String):
print("{", this.multiplayer.multiplayer_peer.get_unique_id(), "} ", string)