92 lines
3.0 KiB
GDScript
92 lines
3.0 KiB
GDScript
extends Node2D
|
|
|
|
@onready var tile_map = $TileMapLayer
|
|
@onready var players_container = $PlayersContainer
|
|
|
|
var player_nodes := {} # id -> Node
|
|
|
|
func _ready():
|
|
# Visual setup
|
|
tile_map.scale = Vector2(0.5, 0.5)
|
|
|
|
NetworkManager.login_ok.connect(_on_login_ok)
|
|
NetworkManager.player_joined.connect(_on_player_joined)
|
|
NetworkManager.player_left.connect(_on_player_left)
|
|
NetworkManager.player_moved.connect(_on_player_moved)
|
|
NetworkManager.disconnected.connect(_on_disconnected) # Handle disconnect
|
|
NetworkManager.chat_message_received.connect(_on_chat_message_received) # Reuse chat logic if desired
|
|
|
|
# Spawn myself manually since scene_peers excludes self
|
|
_spawn_player(NetworkManager.my_id, NetworkManager.player_info["name"], 0, 0, NetworkManager.player_info["skin_id"])
|
|
|
|
# Spawn existing players (including self if already in list, but we usually spawn self manually or via list)
|
|
# Since we just transitioned, NetworkManager.players contains the new list from 'scene_peers' message
|
|
for id in NetworkManager.players:
|
|
var p = NetworkManager.players[id]
|
|
_spawn_player(id, p["name"], p["x"], p["y"], p.get("skin_id", 0))
|
|
|
|
# Chat UI
|
|
var chat = preload("res://Scenes/UI/ChatHUD.tscn").instantiate()
|
|
add_child(chat)
|
|
|
|
func _spawn_player(id, _p_name, x, y, _skin_id):
|
|
if player_nodes.has(id): return # Prevent duplicate
|
|
|
|
var p = preload("res://Scenes/Player.tscn").instantiate()
|
|
p.name = str(id)
|
|
|
|
# For local player in Room, we might want a fixed spawn point (0,0) or the one from server
|
|
# If it's local player, we usually force it to (0,0) on entry
|
|
if id == NetworkManager.my_id:
|
|
p.position = Vector2(0, 0)
|
|
else:
|
|
p.position = Vector2(x, y)
|
|
|
|
p.player_id = id
|
|
p.is_local = (id == NetworkManager.my_id)
|
|
|
|
players_container.add_child(p)
|
|
player_nodes[id] = p
|
|
|
|
if p.is_local:
|
|
var camera = Camera2D.new()
|
|
camera.make_current()
|
|
p.add_child(camera)
|
|
|
|
func _on_login_ok(_my_id, _players):
|
|
# Refresh players if we get a full update
|
|
for id in player_nodes:
|
|
if id != NetworkManager.my_id:
|
|
player_nodes[id].queue_free()
|
|
player_nodes.clear()
|
|
|
|
for id in NetworkManager.players:
|
|
var p = NetworkManager.players[id]
|
|
_spawn_player(id, p["name"], p["x"], p["y"], p.get("skin_id", 0))
|
|
|
|
func _on_player_joined(id, p_name, x, y, skin_id):
|
|
_spawn_player(id, p_name, x, y, skin_id)
|
|
|
|
func _on_player_left(id):
|
|
if player_nodes.has(id):
|
|
player_nodes[id].queue_free()
|
|
player_nodes.erase(id)
|
|
|
|
func _on_player_moved(id, x, y, flip_h, frame):
|
|
if player_nodes.has(id):
|
|
player_nodes[id].set_remote_state(Vector2(x, y), flip_h, frame)
|
|
|
|
func _on_chat_message_received(sender_id, text):
|
|
# Chat HUD handles it via signals usually, but if we need bubbles:
|
|
if player_nodes.has(sender_id):
|
|
player_nodes[sender_id].show_bubble(text)
|
|
|
|
func _on_disconnected():
|
|
get_tree().change_scene_to_file("res://Scenes/StartMenu.tscn")
|
|
|
|
func _on_exit_body_entered(body):
|
|
if body.name == str(NetworkManager.my_id):
|
|
# Return to the world
|
|
NetworkManager.send_change_scene("world", NetworkManager.next_spawn_position)
|
|
get_tree().change_scene_to_file("res://Scenes/World.tscn")
|