From 2a9cbb1fa0268c3be828c0d872180282704abb61 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Thu, 28 Dec 2023 08:48:41 +0100 Subject: show other player puppets --- Characters/Character.gd | 4 +++ Enum.gd | 4 --- Global.gd | 26 +++++++++------ Levels/Level.gd | 19 +++++++++++ Network/Lobby.gd | 9 +++--- Network/Network.gd | 84 ++++++++++++++++++++++++++++++++++--------------- UI/HUD/LevelMapCell.gd | 11 ++----- UI/LevelSelectCell.gd | 11 ++----- 8 files changed, 107 insertions(+), 61 deletions(-) diff --git a/Characters/Character.gd b/Characters/Character.gd index fc33096..ee10c0e 100644 --- a/Characters/Character.gd +++ b/Characters/Character.gd @@ -111,6 +111,10 @@ func _physics_process(delta): velocity = velocity.lerp(Vector2(0, velocity.y), 0.7) move_and_slide() + + if Network.player.position != self.position: + Network.player.position = self.position + Network.update_player() func is_running(): diff --git a/Enum.gd b/Enum.gd index 8fdff6f..c59c707 100644 --- a/Enum.gd +++ b/Enum.gd @@ -6,10 +6,6 @@ const DIRECTION = { RIGHT = 1, } -enum PLAYER { - FIRST, SECOND, THIRD, -} - enum ACTIONS { DIRECTION_LEFT, DIRECTION_RIGHT, JUMP, diff --git a/Global.gd b/Global.gd index 0af9e5c..33fad31 100644 --- a/Global.gd +++ b/Global.gd @@ -38,9 +38,9 @@ func init_level_map(): for level in self.Levels: self.Level_Map.push_back({ time = 0, - cleared_by = { # Network.player - idx = -1, - name = "" + cleared_by = { + id = -1, + player = Network.create_player(), # NetworkPlayer }, meta = { path = "res://Levels/%s.tscn" % level, @@ -72,6 +72,9 @@ func get_instance_level(idx): func start_level(idx): + Network.player.current_level = idx + Network.update_player() + var instance_level = self.get_instance_level(idx) self.change_scene_to_instance(instance_level) @@ -82,7 +85,10 @@ func end_level(instance_level): var time = snapped(instance_level.timer, 0.01) if (global_level.time == 0 or time < global_level.time): global_level.time = time - global_level.cleared_by = Network.player + global_level.cleared_by = { + id = Network.peer.get_unique_id(), + player = Network.player, + } for id in Network.players: rpc_id(id, "_update_level_map", instance_level.idx, global_level) @@ -92,6 +98,8 @@ func end_level(instance_level): func cancel_level(): + Network.player.current_level = -1 + Network.update_player() get_tree().change_scene_to_file("res://UI/LevelSelect.tscn") @@ -118,12 +126,12 @@ func _on_Network_game_ended(): self.init() -func has_won(): +func check_has_won(): var has_won = false var cleared_levels_idx = [] for idx in range(self.Level_Map.size()): - if self.Level_Map[idx].cleared_by.idx == Network.player.idx: + if self.Level_Map[idx].cleared_by.id == Network.peer.get_unique_id(): cleared_levels_idx.push_back(idx) var possible_winning_conditions = [ @@ -154,7 +162,7 @@ func has_won(): func check_win(): - var has_won = self.has_won() + var has_won = self.check_has_won() if has_won: # TODO: start 10s timer with callback check_win_timer() @@ -167,9 +175,9 @@ func check_win(): func check_win_timer(): - var has_won = self.has_won() + #var has_won = self.check_has_won() - if self.has_won(): + if self.check_has_won(): emit_signal("game_won", Network.player) diff --git a/Levels/Level.gd b/Levels/Level.gd index 910feb8..17975ef 100644 --- a/Levels/Level.gd +++ b/Levels/Level.gd @@ -19,6 +19,25 @@ func _ready(): character = load("res://Characters/" + Network.player.character + ".tscn").instantiate() self.set_player(character) + Network.connect("player_changed", func(id): + var remote_player = Network.players[id] + var node_name = "%s_%s_%s" % [remote_player.name, remote_player.character, id] + var puppet = self.get_node(node_name) + + if remote_player.current_level != self.idx: + if puppet: + puppet.queue_free() + return + + if not puppet: + puppet = load("res://Characters/" + remote_player.character + ".tscn").instantiate() + puppet.process_mode = PROCESS_MODE_DISABLED + self.add_child(puppet) + puppet.name = node_name + else: + puppet.position = remote_player.position + ) + if has_node("ParallaxBackground"): $ParallaxBackground/ParallaxLayer.motion_mirroring.x = ( $ParallaxBackground/ParallaxLayer/Sprite2D.get_rect().size diff --git a/Network/Lobby.gd b/Network/Lobby.gd index 80b663b..87a3894 100644 --- a/Network/Lobby.gd +++ b/Network/Lobby.gd @@ -25,7 +25,7 @@ func _ready(): elif OS.has_environment("USER"): ConnectNode.get_node("Name").text = OS.get_environment("USER") else: - var desktop_path = OS.get_system_dir(0).replace("\\", "/").split("/") + var desktop_path = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP).replace("\\", "/").split("/") ConnectNode.get_node("Name").text = desktop_path[desktop_path.size() - 2] # show lobby if we're already connected somewhere @@ -35,9 +35,10 @@ func _ready(): self.refresh_lobby() -func disable_connect_buttons(is_disabled = true): - ConnectNode.get_node("Host").disabled = is_disabled - ConnectNode.get_node("Join").disabled = is_disabled +func disable_connect_buttons(_is_disabled = true): + pass + #ConnectNode.get_node("Host").disabled = is_disabled + #ConnectNode.get_node("Join").disabled = is_disabled func refresh_lobby(): diff --git a/Network/Network.gd b/Network/Network.gd index 1222b92..ce4952c 100644 --- a/Network/Network.gd +++ b/Network/Network.gd @@ -4,31 +4,37 @@ extends Node signal connection_succeeded() signal connection_failed() signal player_list_changed() +signal player_changed() signal game_error() signal game_started() signal game_ended() const PORT = 10567 - const MAX_PEERS = 2 - - var peer: ENetMultiplayerPeer = null -var player = { - idx = 0, - name = "", - character = "Tux", -} + +var player = null var winning_player = player -# Dictionary { id = { idx: 1, name: "" } } +# Dictionary { id = player } var players = {} -var players_ready = [] + +func create_player(): + return { + name = "", + character = "", + symbol = "", + components = [], + current_level = -1, + position = Vector2(0, 0), + } func _ready(): + self.player = self.create_player() + multiplayer.connect("peer_connected", Callable(self, '_player_connected')) multiplayer.connect("peer_disconnected", Callable(self, "_player_disconnected")) multiplayer.connect("connected_to_server", Callable(self, "_connection_succeeded")) @@ -41,18 +47,28 @@ func _ready(): @rpc("any_peer") func register_player(player_name): var id = multiplayer.get_remote_sender_id() - self.players[id] = { - name = player_name, - ip = self.peer.get_peer(id).get_remote_address(), - } + + var network_player = self.create_player() + network_player.name = player_name + self.players[id] = network_player + emit_signal("player_list_changed") -@rpc("any_peer") func unregister_player(id): +func unregister_player(id): self.players.erase(id) emit_signal("player_list_changed") +func update_player(): + rpc("remote_update_player", self.player) + +@rpc("any_peer") func remote_update_player(network_player): + var id = multiplayer.get_remote_sender_id() + self.players[id] = network_player + emit_signal("player_changed", id) + + func host_game(player_name): self.player.name = player_name self.peer = ENetMultiplayerPeer.new() @@ -70,6 +86,7 @@ func join_game(ip, player_name): func leave_game(): rpc("_leave_game") multiplayer.multiplayer_peer = null + self.players = [] @rpc("any_peer") func _leave_game(): @@ -82,23 +99,34 @@ func get_player_count(): func _on_Global_game_started(): - # preconfigure game and set idx to each player + # set symbols + self.player.symbol = "X" var idx = 1 for id in self.players: - self.players[id].idx = idx - rpc_id(id, "_preconfigure_game", idx, Global.Level_Map) + self.players[id].symbol = ["X", "O", "P"][idx] idx += 1 + # preconfigure game + var all_players = self.players.duplicate() + all_players[1] = self.player + rpc("_preconfigure_game", { + level_map = Global.Level_Map, + players = all_players, + }) + # start game for everyone rpc("_start_game") -@rpc("any_peer") func _preconfigure_game(idx, level_map): - self.player.idx = idx - Global.Level_Map = level_map +@rpc("any_peer") func _preconfigure_game(configuration): + Global.Level_Map = configuration.level_map + self.player = configuration.players[multiplayer.get_unique_id()] + configuration.players.erase(multiplayer.get_unique_id()) + self.players = configuration.players @rpc("any_peer", "call_local") func _start_game(): + rpc("remote_update_player", self.player) emit_signal("game_started") @@ -107,12 +135,12 @@ func _on_Global_game_ended(): rpc("_end_game") -func _on_Global_game_won(winning_player): - rpc("_end_game", winning_player) +func _on_Global_game_won(winning_player_object): + rpc("_end_game", winning_player_object) -@rpc("any_peer", "call_local") func _end_game(winning_player): - self.winning_player = winning_player +@rpc("any_peer", "call_local") func _end_game(winning_player_object): + self.winning_player = winning_player_object emit_signal("game_ended") @@ -125,7 +153,8 @@ func _player_disconnected(id): # self.end_game() ? # else #rpc("unregister_player", id) - rpc("unregister_player", id) + #rpc("unregister_player", id) + self.unregister_player(id) func _connection_succeeded(): @@ -134,9 +163,12 @@ func _connection_succeeded(): func _connection_failed(): multiplayer.multiplayer_peer = null # remove peer + self.players = [] emit_signal("connection_failed") func _server_disconnected(): emit_signal("game_error", "Server disconnected!") + multiplayer.multiplayer_peer = null + self.players = [] #self.end_game("") diff --git a/UI/HUD/LevelMapCell.gd b/UI/HUD/LevelMapCell.gd index f66c8c3..d8790dd 100644 --- a/UI/HUD/LevelMapCell.gd +++ b/UI/HUD/LevelMapCell.gd @@ -7,16 +7,9 @@ var level_idx = 0 func _ready(): var level = Global.get_level(self.level_idx) - $ClearMark.text = "" - if level.cleared_by.idx == Enum.PLAYER.FIRST: - $ClearMark.text = "X" - elif level.cleared_by.idx == Enum.PLAYER.SECOND: - $ClearMark.text = "O" - elif level.cleared_by.idx == Enum.PLAYER.THIRD: - $ClearMark.text = "P" - + $ClearMark.text = level.cleared_by.player.symbol $Time.text = str(level.time) + "s" - $Name.text = level.cleared_by.name + $Name.text = level.cleared_by.player.name func set_rect_size(x, y): diff --git a/UI/LevelSelectCell.gd b/UI/LevelSelectCell.gd index cd59593..63380f6 100644 --- a/UI/LevelSelectCell.gd +++ b/UI/LevelSelectCell.gd @@ -13,16 +13,9 @@ func _ready(): stylebox = self.get("theme_override_styles/panel") - $ClearMark.text = "" - if level.cleared_by.idx == Enum.PLAYER.FIRST: - $ClearMark.text = "X" - elif level.cleared_by.idx == Enum.PLAYER.SECOND: - $ClearMark.text = "O" - elif level.cleared_by.idx == Enum.PLAYER.THIRD: - $ClearMark.text = "P" - + $ClearMark.text = level.cleared_by.player.symbol $Time.text = str(level.time) + "s" - $Name.text = level.cleared_by.name + $Name.text = level.cleared_by.player.name func set_rect_size(x, y): -- cgit v1.2.3