Files
whale_town/Scripts/Room.gd
WangXiang 6119faf53e init
2025-12-22 18:57:51 +08:00

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")