feat: Add initial lobby and main scenes with Nakama and lobby management scripts.
This commit is contained in:
+246
@@ -0,0 +1,246 @@
|
||||
extends Control
|
||||
|
||||
# UI References - Main Menu
|
||||
@onready var main_menu_panel = $MainMenuPanel
|
||||
@onready var player_name_input = $MainMenuPanel/VBoxContainer/InputSection/PlayerNameInput
|
||||
@onready var create_room_btn = $MainMenuPanel/VBoxContainer/ButtonSection/CreateRoomBtn
|
||||
@onready var browse_rooms_btn = $MainMenuPanel/VBoxContainer/ButtonSection/BrowseRoomsBtn
|
||||
|
||||
# UI References - Room List
|
||||
@onready var room_list_panel = $RoomListPanel
|
||||
@onready var room_list = $RoomListPanel/VBoxContainer/RoomList
|
||||
@onready var match_id_input = $RoomListPanel/VBoxContainer/MatchIdInput
|
||||
@onready var refresh_btn = $RoomListPanel/VBoxContainer/ButtonContainer/RefreshBtn
|
||||
@onready var join_btn = $RoomListPanel/VBoxContainer/ButtonContainer/JoinBtn
|
||||
@onready var back_btn = $RoomListPanel/VBoxContainer/ButtonContainer/BackBtn
|
||||
|
||||
# UI References - Lobby
|
||||
@onready var lobby_panel = $LobbyPanel
|
||||
@onready var room_name_header = $LobbyPanel/VBoxContainer/RoomNameHeader
|
||||
@onready var match_id_display = $LobbyPanel/VBoxContainer/MatchIdContainer/MatchIdDisplay
|
||||
@onready var copy_id_btn = $LobbyPanel/VBoxContainer/MatchIdContainer/CopyIdBtn
|
||||
@onready var player_list = $LobbyPanel/VBoxContainer/PlayerList
|
||||
@onready var status_label = $LobbyPanel/VBoxContainer/StatusLabel
|
||||
@onready var ready_btn = $LobbyPanel/VBoxContainer/ButtonContainer/ReadyBtn
|
||||
@onready var start_game_btn = $LobbyPanel/VBoxContainer/ButtonContainer/StartGameBtn
|
||||
@onready var leave_btn = $LobbyPanel/VBoxContainer/ButtonContainer/LeaveBtn
|
||||
|
||||
# UI References - Status
|
||||
@onready var connection_status = $StatusBar/ConnectionStatus
|
||||
|
||||
# Store current match ID for copy function
|
||||
var current_match_id: String = ""
|
||||
|
||||
func _ready():
|
||||
# Connect button signals
|
||||
create_room_btn.pressed.connect(_on_create_room_pressed)
|
||||
browse_rooms_btn.pressed.connect(_on_browse_rooms_pressed)
|
||||
refresh_btn.pressed.connect(_on_refresh_pressed)
|
||||
join_btn.pressed.connect(_on_join_pressed)
|
||||
back_btn.pressed.connect(_on_back_pressed)
|
||||
ready_btn.toggled.connect(_on_ready_toggled)
|
||||
start_game_btn.pressed.connect(_on_start_game_pressed)
|
||||
leave_btn.pressed.connect(_on_leave_pressed)
|
||||
copy_id_btn.pressed.connect(_on_copy_id_pressed)
|
||||
|
||||
# Connect LobbyManager signals
|
||||
LobbyManager.room_list_updated.connect(_on_room_list_updated)
|
||||
LobbyManager.room_joined.connect(_on_room_joined)
|
||||
LobbyManager.room_left.connect(_on_room_left)
|
||||
LobbyManager.player_joined.connect(_on_player_joined)
|
||||
LobbyManager.player_left.connect(_on_player_left)
|
||||
LobbyManager.ready_state_changed.connect(_on_ready_state_changed)
|
||||
LobbyManager.all_players_ready.connect(_on_all_players_ready)
|
||||
LobbyManager.game_starting.connect(_on_game_starting)
|
||||
|
||||
# Connect NakamaManager signals
|
||||
NakamaManager.connected_to_nakama.connect(_on_connected_to_nakama)
|
||||
NakamaManager.connection_failed.connect(_on_connection_failed)
|
||||
|
||||
# Show main menu initially
|
||||
_show_panel("main_menu")
|
||||
|
||||
# =============================================================================
|
||||
# Panel Management
|
||||
# =============================================================================
|
||||
|
||||
func _show_panel(panel_name: String) -> void:
|
||||
main_menu_panel.visible = panel_name == "main_menu"
|
||||
room_list_panel.visible = panel_name == "room_list"
|
||||
lobby_panel.visible = panel_name == "lobby"
|
||||
|
||||
# =============================================================================
|
||||
# Main Menu Button Handlers
|
||||
# =============================================================================
|
||||
|
||||
func _on_create_room_pressed() -> void:
|
||||
# Set player name
|
||||
LobbyManager.local_player_name = player_name_input.text.strip_edges()
|
||||
if LobbyManager.local_player_name.is_empty():
|
||||
LobbyManager.local_player_name = "Host"
|
||||
|
||||
connection_status.text = "Creating room..."
|
||||
# Room name auto-generated since Nakama doesn't support custom names
|
||||
LobbyManager.create_room("Room %d" % randi_range(1000, 9999))
|
||||
|
||||
func _on_browse_rooms_pressed() -> void:
|
||||
_show_panel("room_list")
|
||||
connection_status.text = "Loading rooms..."
|
||||
LobbyManager.refresh_room_list()
|
||||
|
||||
# =============================================================================
|
||||
# Room List Button Handlers
|
||||
# =============================================================================
|
||||
|
||||
func _on_refresh_pressed() -> void:
|
||||
connection_status.text = "Refreshing..."
|
||||
room_list.clear()
|
||||
LobbyManager.refresh_room_list()
|
||||
|
||||
func _on_join_pressed() -> void:
|
||||
# First check if there's a match ID entered
|
||||
var match_id = match_id_input.text.strip_edges()
|
||||
|
||||
if match_id.is_empty():
|
||||
# Try to use selected room from list
|
||||
var selected_items = room_list.get_selected_items()
|
||||
if selected_items.size() == 0:
|
||||
connection_status.text = "Please select a room or enter Match ID"
|
||||
return
|
||||
|
||||
var selected_idx = selected_items[0]
|
||||
if selected_idx < LobbyManager.available_rooms.size():
|
||||
match_id = LobbyManager.available_rooms[selected_idx].get("match_id", "")
|
||||
|
||||
if match_id.is_empty():
|
||||
connection_status.text = "No room selected"
|
||||
return
|
||||
|
||||
# Set player name
|
||||
LobbyManager.local_player_name = player_name_input.text.strip_edges()
|
||||
if LobbyManager.local_player_name.is_empty():
|
||||
LobbyManager.local_player_name = "Player"
|
||||
|
||||
connection_status.text = "Joining room..."
|
||||
LobbyManager.join_room(match_id)
|
||||
|
||||
func _on_back_pressed() -> void:
|
||||
_show_panel("main_menu")
|
||||
connection_status.text = ""
|
||||
|
||||
# =============================================================================
|
||||
# Lobby Button Handlers
|
||||
# =============================================================================
|
||||
|
||||
func _on_ready_toggled(is_ready: bool) -> void:
|
||||
LobbyManager.set_ready(is_ready)
|
||||
ready_btn.text = "READY ✓" if is_ready else "READY"
|
||||
|
||||
func _on_start_game_pressed() -> void:
|
||||
LobbyManager.start_game()
|
||||
|
||||
func _on_leave_pressed() -> void:
|
||||
LobbyManager.leave_room()
|
||||
_show_panel("main_menu")
|
||||
ready_btn.button_pressed = false
|
||||
ready_btn.text = "READY"
|
||||
|
||||
func _on_copy_id_pressed() -> void:
|
||||
DisplayServer.clipboard_set(current_match_id)
|
||||
connection_status.text = "Match ID copied to clipboard!"
|
||||
|
||||
# =============================================================================
|
||||
# LobbyManager Signal Handlers
|
||||
# =============================================================================
|
||||
|
||||
func _on_room_list_updated(rooms: Array) -> void:
|
||||
room_list.clear()
|
||||
for room in rooms:
|
||||
var room_name = room.get("room_name", "Unknown")
|
||||
var host_name = room.get("host_name", "Unknown")
|
||||
var player_count = room.get("player_count", 1)
|
||||
var max_players = room.get("max_players", 4)
|
||||
room_list.add_item("%s - %s (%d/%d)" % [room_name, host_name, player_count, max_players])
|
||||
|
||||
if rooms.size() == 0:
|
||||
connection_status.text = "No rooms available"
|
||||
else:
|
||||
connection_status.text = "Found %d room(s)" % rooms.size()
|
||||
|
||||
func _on_room_joined(room_data: Dictionary) -> void:
|
||||
_show_panel("lobby")
|
||||
current_match_id = room_data.get("match_id", "")
|
||||
room_name_header.text = "ROOM: %s" % room_data.get("room_name", "Unknown")
|
||||
match_id_display.text = "Match ID: %s " % current_match_id
|
||||
|
||||
# Update start button visibility (host only)
|
||||
start_game_btn.visible = LobbyManager.is_host
|
||||
|
||||
_update_player_list()
|
||||
connection_status.text = "Connected to room"
|
||||
|
||||
func _on_room_left() -> void:
|
||||
_show_panel("main_menu")
|
||||
connection_status.text = "Left room"
|
||||
|
||||
func _on_player_joined(player_data: Dictionary) -> void:
|
||||
_update_player_list()
|
||||
status_label.text = "%s joined!" % player_data.get("name", "Player")
|
||||
|
||||
func _on_player_left(_player_id: int) -> void:
|
||||
_update_player_list()
|
||||
status_label.text = "A player left"
|
||||
|
||||
func _on_ready_state_changed(_player_id: int, _is_ready: bool) -> void:
|
||||
_update_player_list()
|
||||
_update_status()
|
||||
|
||||
func _on_all_players_ready() -> void:
|
||||
if LobbyManager.is_host:
|
||||
start_game_btn.disabled = false
|
||||
status_label.text = "All players ready! Host can start."
|
||||
else:
|
||||
status_label.text = "All players ready! Waiting for host..."
|
||||
|
||||
func _on_game_starting() -> void:
|
||||
connection_status.text = "Starting game..."
|
||||
# Small delay for visual feedback
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
get_tree().change_scene_to_file("res://scenes/main.tscn")
|
||||
|
||||
# =============================================================================
|
||||
# NakamaManager Signal Handlers
|
||||
# =============================================================================
|
||||
|
||||
func _on_connected_to_nakama() -> void:
|
||||
connection_status.text = "Connected to server"
|
||||
|
||||
func _on_connection_failed(error_message: String) -> void:
|
||||
connection_status.text = "Connection failed: %s" % error_message
|
||||
_show_panel("main_menu")
|
||||
|
||||
# =============================================================================
|
||||
# Helper Functions
|
||||
# =============================================================================
|
||||
|
||||
func _update_player_list() -> void:
|
||||
player_list.clear()
|
||||
var players = LobbyManager.get_players()
|
||||
for player in players:
|
||||
var player_name = player.get("name", "Unknown")
|
||||
var is_ready = player.get("is_ready", false)
|
||||
var ready_icon = " ✓" if is_ready else " ✗"
|
||||
var host_tag = " (Host)" if player.get("id") == 1 else ""
|
||||
player_list.add_item("%s%s%s" % [player_name, host_tag, ready_icon])
|
||||
|
||||
func _update_status() -> void:
|
||||
var players = LobbyManager.get_players()
|
||||
var ready_count = 0
|
||||
for player in players:
|
||||
if player.get("is_ready", false):
|
||||
ready_count += 1
|
||||
|
||||
status_label.text = "Ready: %d/%d" % [ready_count, players.size()]
|
||||
|
||||
if LobbyManager.is_host:
|
||||
start_game_btn.disabled = not LobbyManager.is_all_ready()
|
||||
Reference in New Issue
Block a user