From da88be55675374837550c63e843d8a585dcd871b Mon Sep 17 00:00:00 2001 From: Tiger Date: Mon, 27 Apr 2026 14:07:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=88=E5=B9=B6MultiGame.gd=E5=92=8C?= =?UTF-8?q?GameLoopManager.gd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- project.godot | 1 - scripts/autoload/GameLoopManager.gd | 188 +++++++++++++++++++++++++--- scripts/autoload/MultiGame.gd | 175 -------------------------- scripts/autoload/MultiGame.gd.uid | 1 - scripts/main_menu/create_game_ui.gd | 4 +- scripts/main_menu/join_game_ui.gd | 2 +- 6 files changed, 176 insertions(+), 195 deletions(-) delete mode 100644 scripts/autoload/MultiGame.gd delete mode 100644 scripts/autoload/MultiGame.gd.uid diff --git a/project.godot b/project.godot index 0bbb471..7c02f1f 100644 --- a/project.godot +++ b/project.godot @@ -21,7 +21,6 @@ config/icon="res://icon.svg" [autoload] -MultiGame="*res://scripts/autoload/MultiGame.gd" SceneManager="*res://scripts/autoload/SceneManager.gd" GameManager="*res://scripts/autoload/GameManager.gd" DownloadManager="*res://scripts/autoload/DownloadManager.gd" diff --git a/scripts/autoload/GameLoopManager.gd b/scripts/autoload/GameLoopManager.gd index 16a3d76..89c26ab 100644 --- a/scripts/autoload/GameLoopManager.gd +++ b/scripts/autoload/GameLoopManager.gd @@ -1,26 +1,184 @@ extends Node -var game_round: int = -1 +var PORT: int = 8989 +const MAX_HAND_SIZE: int = 8 +const INITIAL_HP: int = 4 +const DEFAULT_DRAW_COUNT: int = 4 +const FIRST_ROUND_DRAW_COUNT: int = 3 -signal end_game +var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() + +var players: Array[int] = [] +var max_players: int = 0 +var player_cards: Dictionary = {} +var player_turns: Dictionary = {} +var player_username: Dictionary = {} +var player_hp: Dictionary = {} + +var cards: Array[String] = [] +var my_card: Array[String] = [] + +var server_round: int = 0 +var game_started: bool = false + +signal game_end func _ready() -> void: - end_game.connect(_on_end_game) + game_end.connect(_on_end_game) + +func add_player(id: int) -> void: + if players.size() >= max_players or players.has(id): + return + players.append(id) + player_cards[id] = [] + player_turns[id] = 0 + player_hp[id] = INITIAL_HP + + +func remove_player(id: int) -> void: + if not players.has(id): + return + players.erase(id) + for dict in [player_cards, player_turns, player_hp, player_username]: + dict.erase(id) + + +func create_server(playern: int) -> void: + max_players = playern + if peer.create_server(PORT, playern) != OK: + return + _setup_multiplayer() + add_player(1) + + +func create_client(ip: String) -> void: + if peer.create_client(ip, PORT) != OK: + return + _setup_multiplayer() + + +func _setup_multiplayer() -> void: + multiplayer.multiplayer_peer = peer + multiplayer.peer_connected.connect(_on_peer_connected) + multiplayer.peer_disconnected.connect(_on_peer_disconnected) + + +func _on_peer_connected(id: int) -> void: + add_player(id) + sync_players.rpc() + + +func _on_peer_disconnected(id: int) -> void: + remove_player(id) + sync_players.rpc() func start_game() -> void: - game_round = 1 - - -func settle_round() -> void: - game_round += 1 - if check_game_end(): - end_game.emit() - - -func check_game_end() -> bool: - return false + if not multiplayer.is_server() or players.size() != max_players: + return + game_started = true + server_round = 1 + deal_cards() + sync_game_state.rpc() func _on_end_game() -> void: - game_round = -1 + pass + + +func extract() -> String: + if cards.is_empty(): + return "" + var index := randi() % cards.size() + var card := cards[index] + cards.remove_at(index) + return card + + +func deal_cards() -> void: + for player_id in players: + _draw_cards(player_id, MAX_HAND_SIZE) + + +func next_round() -> void: + if not multiplayer.is_server(): + return + settle_round() + server_round += 1 + sync_game_state.rpc() + + +func settle_round() -> void: + for player_id in players: + var draw_count := DEFAULT_DRAW_COUNT + if server_round == 1 and player_turns.get(player_id, -1) <= 1: + draw_count = FIRST_ROUND_DRAW_COUNT + _draw_cards(player_id, draw_count) + + +func _draw_cards(player_id: int, count: int) -> void: + if not player_cards.has(player_id): + return + var hand: Array = player_cards[player_id] + for i in count: + if hand.size() >= MAX_HAND_SIZE: + break + var card := extract() + if card.is_empty(): + break + hand.append(card) + + +func get_my_cards() -> void: + request_cards.rpc_id(1) + + +@rpc("any_peer", "call_remote", "reliable") +func request_cards() -> void: + var sender_id := multiplayer.get_remote_sender_id() + send_cards.rpc_id(sender_id, player_cards.get(sender_id, [])) + + +@rpc("authority", "call_remote", "reliable") +func send_cards(data: Array) -> void: + my_card = data + + +func sync_game_state() -> void: + if not multiplayer.is_server(): + return + sync_game_state_rpc.rpc({ + cards = cards, + player_cards = player_cards, + player_turns = player_turns, + player_hp = player_hp, + server_round = server_round, + game_started = game_started + }) + + +@rpc("authority", "call_remote", "reliable") +func sync_game_state_rpc(data: Dictionary) -> void: + cards = data.cards + player_cards = data.player_cards + player_turns = data.player_turns + player_hp = data.player_hp + server_round = data.server_round + game_started = data.game_started + + +func sync_players() -> void: + if not multiplayer.is_server(): + return + sync_players_rpc.rpc({ + players = players, + player_username = player_username, + player_hp = player_hp + }) + + +@rpc("authority", "call_remote", "reliable") +func sync_players_rpc(data: Dictionary) -> void: + players = data.players + player_username = data.player_username + player_hp = data.player_hp diff --git a/scripts/autoload/MultiGame.gd b/scripts/autoload/MultiGame.gd deleted file mode 100644 index 516b2d0..0000000 --- a/scripts/autoload/MultiGame.gd +++ /dev/null @@ -1,175 +0,0 @@ -extends Node - -var PORT: int = 8989 -const MAX_HAND_SIZE: int = 8 -const INITIAL_HP: int = 4 -const DEFAULT_DRAW_COUNT: int = 4 -const FIRST_ROUND_DRAW_COUNT: int = 3 - -var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() - -var players: Array[int] = [] -var max_players: int = 0 -var player_cards: Dictionary = {} -var player_turns: Dictionary = {} -var player_username: Dictionary = {} -var player_hp: Dictionary = {} - -var cards: Array[String] = [] -var my_card: Array[String] = [] - -var server_round: int = 0 -var game_started: bool = false - -func add_player(id: int) -> void: - if players.size() >= max_players or players.has(id): - return - players.append(id) - player_cards[id] = [] - player_turns[id] = 0 - player_hp[id] = INITIAL_HP - - -func remove_player(id: int) -> void: - if not players.has(id): - return - players.erase(id) - for dict in [player_cards, player_turns, player_hp, player_username]: - dict.erase(id) - - -func create_server(playern: int) -> void: - max_players = playern - if peer.create_server(PORT, playern) != OK: - return - _setup_multiplayer() - add_player(1) - - -func create_client(ip: String) -> void: - if peer.create_client(ip, PORT) != OK: - return - _setup_multiplayer() - - -func _setup_multiplayer() -> void: - multiplayer.multiplayer_peer = peer - multiplayer.peer_connected.connect(_on_peer_connected) - multiplayer.peer_disconnected.connect(_on_peer_disconnected) - - -func _on_peer_connected(id: int) -> void: - add_player(id) - sync_players.rpc() - - -func _on_peer_disconnected(id: int) -> void: - remove_player(id) - sync_players.rpc() - - -func start_game() -> void: - if not multiplayer.is_server() or players.size() != max_players: - return - game_started = true - server_round = 1 - deal_cards() - sync_game_state.rpc() - - -func extract() -> String: - if cards.is_empty(): - return "" - var index := randi() % cards.size() - var card := cards[index] - cards.remove_at(index) - return card - - -func deal_cards() -> void: - for player_id in players: - _draw_cards(player_id, MAX_HAND_SIZE) - - -func next_round() -> void: - if not multiplayer.is_server(): - return - settle_round() - server_round += 1 - sync_game_state.rpc() - - -func settle_round() -> void: - for player_id in players: - var draw_count := DEFAULT_DRAW_COUNT - if server_round == 1 and player_turns.get(player_id, -1) <= 1: - draw_count = FIRST_ROUND_DRAW_COUNT - _draw_cards(player_id, draw_count) - - -func _draw_cards(player_id: int, count: int) -> void: - if not player_cards.has(player_id): - return - var hand: Array = player_cards[player_id] - for i in count: - if hand.size() >= MAX_HAND_SIZE: - break - var card := extract() - if card.is_empty(): - break - hand.append(card) - - -func get_my_cards() -> void: - request_cards.rpc_id(1) - - -@rpc("any_peer", "call_remote", "reliable") -func request_cards() -> void: - var sender_id := multiplayer.get_remote_sender_id() - send_cards.rpc_id(sender_id, player_cards.get(sender_id, [])) - - -@rpc("authority", "call_remote", "reliable") -func send_cards(data: Array) -> void: - my_card = data - - -func sync_game_state() -> void: - if not multiplayer.is_server(): - return - sync_game_state_rpc.rpc({ - cards = cards, - player_cards = player_cards, - player_turns = player_turns, - player_hp = player_hp, - server_round = server_round, - game_started = game_started - }) - - -@rpc("authority", "call_remote", "reliable") -func sync_game_state_rpc(data: Dictionary) -> void: - cards = data.cards - player_cards = data.player_cards - player_turns = data.player_turns - player_hp = data.player_hp - server_round = data.server_round - game_started = data.game_started - - -func sync_players() -> void: - if not multiplayer.is_server(): - return - sync_players_rpc.rpc({ - players = players, - player_username = player_username, - player_hp = player_hp - }) - - -@rpc("authority", "call_remote", "reliable") -func sync_players_rpc(data: Dictionary) -> void: - players = data.players - player_username = data.player_username - player_hp = data.player_hp diff --git a/scripts/autoload/MultiGame.gd.uid b/scripts/autoload/MultiGame.gd.uid deleted file mode 100644 index 2a42f7c..0000000 --- a/scripts/autoload/MultiGame.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dwbuaieufg51g diff --git a/scripts/main_menu/create_game_ui.gd b/scripts/main_menu/create_game_ui.gd index e56477b..aeec451 100644 --- a/scripts/main_menu/create_game_ui.gd +++ b/scripts/main_menu/create_game_ui.gd @@ -1,9 +1,9 @@ extends Node2D func _on_create_game_button_pressed() -> void: - var player_num = int($CreateGameEdit.text) + var player_num: int = int($CreateGameEdit.text) if 2 <= player_num and player_num <= 4: - MultiGame.create_server(int(player_num)) + GameLoopManager.create_server(int(player_num)) $".".hide() SceneManager.goto_scene("game/game") else: diff --git a/scripts/main_menu/join_game_ui.gd b/scripts/main_menu/join_game_ui.gd index 7b78a49..efdc016 100644 --- a/scripts/main_menu/join_game_ui.gd +++ b/scripts/main_menu/join_game_ui.gd @@ -3,6 +3,6 @@ extends Node2D func _on_join_game_button_pressed() -> void: var ip: String = $JoinGameEdit.text - MultiGame.create_client(ip) + GameLoopManager.create_client(ip) $".".hide() SceneManager.goto_scene("game/game")