Merge branch 'develop' into 'master'

优化代码,准备重写GameLoopManager.gd

See merge request paper-chemis-community/game!7
This commit is contained in:
2026-05-18 09:53:29 +08:00
22 changed files with 474 additions and 207 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
.godot/
.vscode/
.vscode/
.idea/
+31 -25
View File
@@ -14,38 +14,44 @@ game/
- project.godot
- icon.svg
- assets/
- fonts/
- AlibabaPuHuiTi-3-65-Medium.ttf # 阿里巴巴普惠体
- translation/
- trans.csv
- fonts/
- AlibabaPuHuiTi-3-65-Medium.ttf # 阿里巴巴普惠体
- translation/
- trans.csv
- scenes/
- menus/
- main_menu.tscn
- settings.tscn
- game/
- game.tscn
- card.tscn
- menus/
- main_menu.tscn
- settings.tscn
- game/
- game.tscn
- card.tscn
- scripts/
- autoload/
- GameManager.gd # 游戏管理
- DownloadManager.gd # 下载管理
- MultiGame.gd # 多人游戏功能
- SceneManager.gd # 场景管理
- main_menu/
- main_menu.gd
- join_game_ui.gd
- create_game_ui.gd
- game/
- game.gd
- card.gd
- settings/
- settings.gd
- autoload/
- GameManager.gd # 游戏管理
- DownloadManager.gd # 下载管理
- SceneManager.gd # 场景管理
- GameLoopManager.gd # 游戏循环管理
- main_menu/
- main_menu.gd
- join_game_ui.gd
- create_game_ui.gd
- game/
- game.gd
- card.gd
- settings/
- settings.gd
```
## 如何运行
请先运行数据后端,在游戏设置中输入后端 URL(包含端口号和 `http://``https://` 前缀),或者选择本地已有的数据源,然后创建游戏或加入游戏开始游玩。
## 部分游戏逻辑介绍
### 游戏循环
游戏循环管理器(GameLoopManager.gd)负责游戏游戏循环的管理。
## 最佳实践
本项目目前正在使用 Godot 4.6.2 进行开发。开发用语言为 GDScript。
@@ -56,4 +62,4 @@ game/
- 除连接了信号或 HTTPRequest、MultiplayerAPI 的函数外,任何函数都不应该以下划线(`_`)开头。
- 函数之间只需间隔一行,无需间隔两行。
- 函数之间既可间隔一行,也可间隔两行。建议函数间隔两行,部分间隔一行的函数为遗留问题。
+317
View File
@@ -0,0 +1,317 @@
extends Node
var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
var max_player_num: int
var player_num: int
# 玩家数据字典 [peer_id: {"name": str, "hand": Array, "score": int, "is_ready": bool}]
var players_data: Dictionary = {}
var current_turn: int = 1 # 当前回合数
var current_player_id: int = 1 # 当前行动玩家的 peer_id
var game_started: bool = false
var game_phase: String = "waiting" # waiting, playing, ended
var deck: Array = [] # 游戏牌组
func create_server(playern: int) -> void:
max_player_num = playern
player_num = 1
if peer.create_server(GameManager.port, playern) != OK:
print("Failed to create server on port: ", GameManager.port)
return
setup_multiplayer()
# 服务器自己也是玩家
players_data[1] = {
"name": "Host",
"hand": [],
"score": 0,
"is_ready": false
}
print("Server created on port: ", GameManager.port)
func create_client(ip: String) -> void:
if peer.create_client(ip, GameManager.port) != OK:
print("Failed to connect to server: ", ip)
return
setup_multiplayer()
print("Connecting to server: ", ip)
func setup_multiplayer() -> void:
multiplayer.multiplayer_peer = peer
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
multiplayer.connected_to_server.connect(_on_connected_to_server)
multiplayer.connection_failed.connect(_on_connection_failed)
func _on_connected_to_server() -> void:
print("Connected to server successfully!")
func _on_connection_failed() -> void:
print("Failed to connect to server")
func _on_peer_connected(id: int) -> void:
print("Peer connected: ", id)
add_player(id)
# 如果游戏未开始且达到最大玩家数,询问是否开始游戏
if !game_started and players_data.size() >= max_player_num:
check_all_players_ready()
func _on_peer_disconnected(id: int):
print("Peer disconnected: ", id)
remove_player(id)
# 如果当前玩家断开,切换到下一个玩家
if id == current_player_id and game_started:
next_turn()
func add_player(id: int) -> void:
# 只有服务器才能添加玩家
if multiplayer.is_server():
players_data[id] = {
"name": "Player_" + str(id),
"hand": [],
"score": 0,
"is_ready": false
}
player_num = players_data.size()
# 广播新玩家加入
broadcast_player_list()
print("Player added: ", id, " Total players: ", player_num)
func remove_player(id: int) -> void:
if multiplayer.is_server() and players_data.has(id):
players_data.erase(id)
player_num = players_data.size()
broadcast_player_list()
print("Player removed: ", id)
# RPC: 设置玩家准备状态
@rpc("any_peer", "call_remote", "reliable")
func set_player_ready(is_ready: bool) -> void:
var peer_id = multiplayer.get_remote_sender_id()
if players_data.has(peer_id):
players_data[peer_id]["is_ready"] = is_ready
broadcast_player_list()
if is_ready:
check_all_players_ready()
# RPC: 设置玩家名称
@rpc("any_peer", "call_remote", "reliable")
func set_player_name(name: String) -> void:
var peer_id = multiplayer.get_remote_sender_id()
if players_data.has(peer_id):
players_data[peer_id]["name"] = name
broadcast_player_list()
# RPC: 开始游戏(仅主机调用)
@rpc("call_remote", "reliable")
func start_game() -> void:
if multiplayer.is_server():
if players_data.size() < 2:
print("Need at least 2 players to start game")
return
game_started = true
game_phase = "playing"
current_turn = 1
initialize_deck()
deal_initial_cards()
# 随机选择第一个玩家
var player_ids = players_data.keys()
current_player_id = player_ids[randi() % player_ids.size()]
print("Game started! Current player: ", current_player_id)
broadcast_game_state()
# 初始化牌组
func initialize_deck() -> void:
deck = []
# 这里可以根据 GameManager 中的卡牌列表初始化牌组
if GameManager.card_list:
for card_id in GameManager.card_list:
# 每张卡牌加入多次(根据游戏需求调整)
for i in range(3): # 每张卡牌3份
deck.append(card_id)
# 洗牌
deck.shuffle()
print("Deck initialized with ", deck.size(), " cards")
# 发放初始手牌
func deal_initial_cards() -> void:
var cards_per_player = 5 # 每个玩家初始手牌数
for peer_id in players_data:
for i in range(cards_per_player):
if deck.size() > 0:
var card_id = deck.pop_front()
players_data[peer_id]["hand"].append(card_id)
broadcast_hands()
# RPC: 抽牌
@rpc("any_peer", "call_remote", "reliable")
func draw_card() -> void:
var peer_id = multiplayer.get_remote_sender_id()
# 检查是否是该玩家的回合
if peer_id != current_player_id:
return
# 检查牌组是否还有牌
if deck.size() == 0:
print("Deck is empty!")
return
var card_id = deck.pop_front()
players_data[peer_id]["hand"].append(card_id)
print("Player ", peer_id, " drew card: ", card_id)
broadcast_hands()
# RPC: 打出卡牌
@rpc("any_peer", "call_remote", "reliable")
func play_card(card_index: int, target_player_id: int = -1) -> void:
var peer_id = multiplayer.get_remote_sender_id()
# 检查是否是该玩家的回合
if peer_id != current_player_id:
return
# 检查卡牌索引是否有效
if card_index < 0 or card_index >= players_data[peer_id]["hand"].size():
return
var card_id = players_data[peer_id]["hand"][card_index]
# 移除手牌中的卡牌
players_data[peer_id]["hand"].remove_at(card_index)
# 执行卡牌效果
execute_card_effect(card_id, peer_id, target_player_id)
print("Player ", peer_id, " played card: ", card_id)
broadcast_hands()
broadcast_game_state()
# 执行卡牌效果
func execute_card_effect(card_id: int, player_id: int, target_id: int) -> void:
# 这里根据卡牌ID执行具体效果
# 示例:简单加分效果
if players_data.has(player_id):
players_data[player_id]["score"] += 10
# 可以添加更多复杂的卡牌效果逻辑
print("Card ", card_id, " effect executed by player ", player_id)
# RPC: 结束回合
@rpc("any_peer", "call_remote", "reliable")
func end_turn() -> void:
var peer_id = multiplayer.get_remote_sender_id()
if peer_id != current_player_id:
return
next_turn()
# 切换到下一个玩家
func next_turn() -> void:
var player_ids = players_data.keys()
var current_index = player_ids.find(current_player_id)
if current_index != -1:
current_index = (current_index + 1) % player_ids.size()
current_player_id = player_ids[current_index]
current_turn += 1
print("Turn ", current_turn, ". Current player: ", current_player_id)
broadcast_game_state()
# 检查所有玩家是否都准备好了
func check_all_players_ready() -> void:
var all_ready = true
for player_id in players_data:
if !players_data[player_id]["is_ready"]:
all_ready = false
break
if all_ready and players_data.size() >= 2:
print("All players ready! Starting game...")
start_game.rpc()
# 广播玩家列表
func broadcast_player_list() -> void:
update_players_data.rpc(players_data)
# RPC: 更新玩家数据
@rpc("call_remote", "reliable")
func update_players_data(data: Dictionary) -> void:
players_data = data
player_num = players_data.size()
emit_signal("players_updated", players_data)
# 广播游戏状态
func broadcast_game_state() -> void:
update_game_state.rpc(game_started, game_phase, current_turn, current_player_id)
# RPC: 更新游戏状态
@rpc("call_remote", "reliable")
func update_game_state(started: bool, phase: String, turn: int, current_id: int) -> void:
game_started = started
game_phase = phase
current_turn = turn
current_player_id = current_id
emit_signal("game_state_updated", game_started, game_phase, current_turn, current_player_id)
# 广播手牌信息(只发给对应玩家)
func broadcast_hands() -> void:
for peer_id in players_data:
send_hand.rpc_id(peer_id, players_data[peer_id]["hand"])
# 发送其他玩家的手牌数量
var hand_sizes = {}
for peer_id in players_data:
hand_sizes[peer_id] = players_data[peer_id]["hand"].size()
broadcast_hand_sizes.rpc(hand_sizes)
# RPC: 发送手牌
@rpc("call_remote", "reliable")
func send_hand(hand: Array) -> void:
var peer_id = multiplayer.get_unique_id()
if players_data.has(peer_id):
players_data[peer_id]["hand"] = hand
emit_signal("hand_updated", hand)
# RPC: 广播手牌数量
@rpc("call_remote", "reliable")
func broadcast_hand_sizes(sizes: Dictionary) -> void:
emit_signal("hand_sizes_updated", sizes)
# RPC: 结束游戏
@rpc("call_remote", "reliable")
func end_game() -> void:
game_started = false
game_phase = "ended"
broadcast_game_state()
# 计算并显示最终得分
var scores = {}
for player_id in players_data:
scores[player_id] = players_data[player_id]["score"]
emit_signal("game_ended", scores)
# 信号定义(需要在编辑器中连接或在其他脚本中连接)
signal players_updated(players: Dictionary)
signal game_state_updated(started: bool, phase: String, turn: int, current_player: int)
signal hand_updated(hand: Array)
signal hand_sizes_updated(sizes: Dictionary)
signal game_ended(scores: Dictionary)
+1
View File
@@ -0,0 +1 @@
uid://dkwc5qney4yee
+5
View File
@@ -0,0 +1,5 @@
# AI 生成代码文件
这个目录下的代码都是 AI 生成的,仅作参考。
不要将本目录下的代码直接复制到被使用的代码处。
+1 -1
View File
@@ -31,4 +31,4 @@ SETTINGS_TIP_LOADED,Tip: Finish Loading,提示:完成加载
SETTINGS_TIP_NOLOCALSOURCE,Tip: No local data or no selection,提示:无本地数据或未选择,无法加载
GAMEUI_URNULL,Room Running: You are XXX XXXX,啊啊啊啊啊:啊啊啊啊
GAMEUI_URHOST,Room Running: You are the Host,房间运行中:您是房主
GAMEUI_URGUEST,Room Running: You are a Guest,房间运行中:您是房客
GAMEUI_URGUEST,Room Running: You are a Guest,房间运行中:您是房客
1 keys en zh-cn
31 SETTINGS_TIP_NOLOCALSOURCE Tip: No local data or no selection 提示:无本地数据或未选择,无法加载
32 GAMEUI_URNULL Room Running: You are XXX XXXX 啊啊啊啊啊:啊啊啊啊
33 GAMEUI_URHOST Room Running: You are the Host 房间运行中:您是房主
34 GAMEUI_URGUEST Room Running: You are a Guest 房间运行中:您是房客
+1 -1
View File
@@ -21,10 +21,10 @@ 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"
GameLoopManager="*uid://qxowgxfp4iwm"
[display]
+4 -4
View File
@@ -7,10 +7,10 @@
script = ExtResource("1_yqjtg")
[node name="Background" type="ColorRect" parent="." unique_id=802635055]
offset_left = -34.0
offset_top = -27.0
offset_right = 2594.0
offset_bottom = 1476.0
offset_left = -29.0
offset_top = -18.0
offset_right = 2599.0
offset_bottom = 1485.0
color = Color(0.7058824, 0.6862745, 0, 1)
[node name="IsServerLabel" type="Label" parent="." unique_id=592205212]
+10 -10
View File
@@ -34,7 +34,7 @@ theme_override_fonts/font = ExtResource("2_6wm04")
theme_override_font_sizes/font_size = 24
[node name="IPBeginSetting" type="Node2D" parent="." unique_id=1428256194]
position = Vector2(-1, 94)
position = Vector2(0, 100)
metadata/_edit_group_ = true
[node name="IPBeginSetLabel" type="Label" parent="IPBeginSetting" unique_id=561890346]
@@ -55,7 +55,7 @@ theme_override_fonts/font = ExtResource("2_6wm04")
theme_override_font_sizes/font_size = 24
[node name="UsernameSetting" type="Node2D" parent="." unique_id=564366013]
position = Vector2(0, 208)
position = Vector2(0, 200)
metadata/_edit_group_ = true
[node name="UsernameSetLabel" type="Label" parent="UsernameSetting" unique_id=1569658441]
@@ -76,7 +76,7 @@ theme_override_fonts/font = ExtResource("2_6wm04")
theme_override_font_sizes/font_size = 24
[node name="LoadSource" type="Node2D" parent="." unique_id=230611076]
position = Vector2(44, 314)
position = Vector2(40, 300)
metadata/_edit_group_ = true
[node name="LoadSourceLabel" type="Label" parent="LoadSource" unique_id=299353496]
@@ -96,7 +96,7 @@ offset_bottom = 60.0
theme_override_font_sizes/font_size = 25
[node name="ChooseLanguage" type="Node2D" parent="." unique_id=323270128]
position = Vector2(39, 405)
position = Vector2(40, 400)
metadata/_edit_group_ = true
[node name="ChooseLanguageLabel" type="Label" parent="ChooseLanguage" unique_id=1719434618]
@@ -130,18 +130,18 @@ theme_override_font_sizes/font_size = 30
text = "SETTINGS_SAVESETTINGS"
[node name="DownloadButton" type="Button" parent="." unique_id=315804661]
offset_left = 598.0
offset_top = 1316.0
offset_right = 774.0
offset_bottom = 1405.0
offset_left = 554.0
offset_top = 1309.0
offset_right = 761.0
offset_bottom = 1398.0
theme_override_fonts/font = ExtResource("2_6wm04")
theme_override_font_sizes/font_size = 30
text = "SETTINGS_DOWNLOAD"
[node name="CancelButton" type="Button" parent="." unique_id=135993345]
offset_left = 371.0
offset_left = 347.0
offset_top = 1305.0
offset_right = 550.0
offset_right = 581.0
offset_bottom = 1394.0
theme_override_fonts/font = ExtResource("2_6wm04")
theme_override_font_sizes/font_size = 30
+28 -21
View File
@@ -3,32 +3,35 @@ extends Node
var uuid: String
func create_file(file_path: String) -> void:
var base_dir = file_path.get_base_dir()
var base_dir: String = file_path.get_base_dir()
if !DirAccess.dir_exists_absolute(base_dir):
DirAccess.make_dir_recursive_absolute(base_dir)
var file = FileAccess.open(file_path, FileAccess.WRITE)
var file: FileAccess = FileAccess.open(file_path, FileAccess.WRITE)
file.close()
func download_file(server_path: String, local_path: String) -> void:
var http = HTTPRequest.new()
var http: HTTPRequest = HTTPRequest.new()
add_child(http)
var file_path = local_path
var file_path: String = local_path
if !FileAccess.file_exists(file_path):
create_file(file_path)
http.download_file = file_path
http.request(server_path)
await http.request_completed
func get_uuid() -> void:
var index_file = FileAccess.open("user://download/sources/temp/index.json", FileAccess.READ)
var index_text = index_file.get_as_text()
var index_file: FileAccess = FileAccess.open("user://download/sources/temp/index.json", FileAccess.READ)
var index_text: String = index_file.get_as_text()
var content = JSON.parse_string(index_text)
index_file.close()
uuid = content["uuid"]
func download_defs(type: String, origin: String) -> void:
var list_file = FileAccess.open("user://download/sources/%s/%ss/list.json" % [uuid, type], FileAccess.READ)
var list_text = list_file.get_as_text()
var list_file: FileAccess = FileAccess.open("user://download/sources/%s/%ss/list.json" % [uuid, type], FileAccess.READ)
var list_text: String = list_file.get_as_text()
var list = JSON.parse_string(list_text)
list_file.close()
if !list:
@@ -37,9 +40,10 @@ func download_defs(type: String, origin: String) -> void:
var filename = list[k]
await download_file("%s%s/id/%s" % [origin, type, k], "user://download/sources/%s/%ss/%s.json" % [uuid, type, filename])
func download_assets(origin: String) -> void:
var list_file = FileAccess.open("user://download/sources/%s/assets/list.json" % [uuid], FileAccess.READ)
var list_text = list_file.get_as_text()
var list_file: FileAccess = FileAccess.open("user://download/sources/%s/assets/list.json" % [uuid], FileAccess.READ)
var list_text: String = list_file.get_as_text()
var list = JSON.parse_string(list_text)
list_file.close()
if !list:
@@ -51,9 +55,10 @@ func download_assets(origin: String) -> void:
var filename = list["sounds"][k]
await download_file("%sasset/sound/%s" % [origin, k], "user://download/sources/%s/assets/sounds/%s" % [uuid, filename])
func download_from_origin() -> int:
var origin = GameManager.data_origin
var http = HTTPRequest.new()
var origin: String = GameManager.data_origin
var http: HTTPRequest = HTTPRequest.new()
add_child(http)
if origin.substr(0, 4) != "http":
@@ -88,35 +93,37 @@ func download_from_origin() -> int:
return 0
func load_resource():
var card_file = FileAccess.open("user://download/sources/%s/cards/list.json" % [uuid], FileAccess.READ)
var card_file: FileAccess = FileAccess.open("user://download/sources/%s/cards/list.json" % [uuid], FileAccess.READ)
GameManager.card_list = JSON.parse_string(card_file.get_as_text())
card_file.close()
var reaction_file = FileAccess.open("user://download/sources/%s/reactions/list.json" % [uuid], FileAccess.READ)
var reaction_file: FileAccess = FileAccess.open("user://download/sources/%s/reactions/list.json" % [uuid], FileAccess.READ)
GameManager.reaction_list = JSON.parse_string(reaction_file.get_as_text())
reaction_file.close()
var matter_file = FileAccess.open("user://download/sources/%s/matters/list.json" % [uuid], FileAccess.READ)
var matter_file: FileAccess = FileAccess.open("user://download/sources/%s/matters/list.json" % [uuid], FileAccess.READ)
GameManager.matter_list = JSON.parse_string(matter_file.get_as_text())
matter_file.close()
var asset_file = FileAccess.open("user://download/sources/%s/assets/list.json" % [uuid], FileAccess.READ)
var asset_list = JSON.parse_string(asset_file.get_as_text())
var asset_file: FileAccess = FileAccess.open("user://download/sources/%s/assets/list.json" % [uuid], FileAccess.READ)
var asset_list: Dictionary = JSON.parse_string(asset_file.get_as_text())
GameManager.pic_list = asset_list["pics"]
GameManager.sound_list = asset_list["sounds"]
asset_file.close()
func get_sources():
if !DirAccess.dir_exists_absolute("user://download/sources/"):
DirAccess.make_dir_recursive_absolute("user://download/sources/")
var dir = DirAccess.open("user://download/sources/")
var dir: DirAccess = DirAccess.open("user://download/sources/")
var subdirs: PackedStringArray = dir.get_directories()
for subdir in subdirs:
if subdir == "temp":
if subdir as String == "temp":
continue
var file = FileAccess.open("user://download/sources/%s/index.json" % [subdir], FileAccess.READ)
var text = file.get_as_text()
var file: FileAccess = FileAccess.open("user://download/sources/%s/index.json" % [subdir], FileAccess.READ)
var text: String = file.get_as_text()
var content = JSON.parse_string(text)
file.close()
var source_name = content["name"]
+45
View File
@@ -0,0 +1,45 @@
extends Node
var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
var max_player_num: int
var player_num: int
func create_server(playern: int) -> void:
max_player_num = playern
player_num = 1
if peer.create_server(GameManager.port, playern) != OK:
return
setup_multiplayer()
func create_client(ip: String) -> void:
if peer.create_client(ip, GameManager.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)
func _on_peer_disconnected(id: int):
remove_player(id)
func add_player(id: int) -> void:
pass
func remove_player(id: int) -> void:
pass
func start_game() -> void:
pass
+1
View File
@@ -0,0 +1 @@
uid://qxowgxfp4iwm
+1
View File
@@ -2,6 +2,7 @@ extends Node
var data_origin: String = ""
var ip_begin: String = "192.168."
var port: int
var username: String = "Player1"
var source: int = -1
-128
View File
@@ -1,128 +0,0 @@
extends Node
var peer = ENetMultiplayerPeer.new()
var players: Array
var cards: Array
var my_card: Array
var max_players: int
var player_cards: Dictionary
var player_turns: Dictionary
var player_username: Dictionary
var player_hp: Dictionary
var server_round: int
var client_round: int
func add_player(id: int):
if players.size() < max_players:
players.append(id)
player_cards[id] = []
func remove_player(id: int):
for i in range(players.size()):
if players[i] == id:
players.pop_at(i)
player_cards.erase(id)
break
func create_server(playern: int) -> void:
max_players = playern
var error = peer.create_server(8989, playern)
if error != OK:
printerr(error)
return
multiplayer.multiplayer_peer = peer
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
func create_client(ip: String) -> void:
peer.create_client(ip, 8989)
multiplayer.multiplayer_peer = peer
func _on_peer_connected(id: int) -> void:
add_player(id)
func _on_peer_disconnected(id: int) -> void:
remove_player(id)
func start_game() -> void:
if players.size() != max_players:
return
deal_cards()
server_round = 1
remote_variable()
func extract() -> String:
if cards.size() == 0:
return ""
var index = randi() % cards.size()
var card = cards[index]
cards.pop_at(index)
return card
func deal_cards() -> void:
for player in players:
while player_cards[player].size() < 8:
var card = extract()
if card != "":
player_cards[player].append(card)
func next_round() -> void:
settle_round()
server_round += 1
func settle_round() -> void:
for player in players:
request_card_draw(player)
remote_variable()
func request_card_draw(player_id: int) -> void:
if server_round == 1 and 0 <= player_turns[player_id] <= 1:
for i in range(3):
if player_cards[player_id].size() >= 8:
break
var card = extract()
if card != "":
player_cards[player_id].append(card)
else:
for i in range(4):
if player_cards[player_id].size() >= 8:
break
var card = extract()
if card != "":
player_cards[player_id].append(card)
remote_variable()
func get_my_cards() -> void:
request_cards.rpc()
@rpc("any_peer", "call_remote", "reliable")
func request_cards() -> void:
var sender_id = multiplayer.get_remote_sender_id()
var data: Array = player_cards.get(sender_id, [-1])
send_cards.rpc_id(sender_id, data)
@rpc("authority", "call_remote", "reliable")
func send_cards(data: Array) -> void:
my_card = data
func remote_variable() -> void:
if not multiplayer.is_server():
return
var data: Dictionary = {}
data["cards"] = cards
data["player_cards"] = player_cards
data["player_turns"] = player_turns
data["player_hp"] = player_hp
data["server_round"] = server_round
get_remote_variable.rpc(data)
@rpc("authority", "call_remote", "reliable")
func get_remote_variable(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"]
-1
View File
@@ -1 +0,0 @@
uid://dwbuaieufg51g
+7 -6
View File
@@ -2,13 +2,14 @@ extends Node
var current_scene = null
var Card = ResourceLoader.load("res://prefabs/game/card.tscn")
var Card: Resource = ResourceLoader.load("res://scenes/game/card.tscn")
func _ready():
var root = get_tree().root
current_scene = root.get_child(root.get_child_count() - 1)
var root: Window = get_tree().root
current_scene = root.get_child(root.get_child_count() - 1)
func goto_scene(path: String):
get_tree().change_scene_to_file("res://scenes/%s.tscn" % [path])
var root = get_tree().root
current_scene = root.get_child(root.get_child_count() - 1)
get_tree().change_scene_to_file("res://scenes/%s.tscn" % [path])
var root: Window = get_tree().root
current_scene = root.get_child(root.get_child_count() - 1)
+5 -1
View File
@@ -4,17 +4,21 @@ var description: String
var type: String
var card_name: String
func set_texture(pic: String) -> void:
var image = Image.new()
var image: Image = Image.new()
image.load(pic)
$Sprite.texture = ImageTexture.create_from_image(image)
func set_card(cname: String) -> void:
card_name = cname
set_texture("user://download/sources/%s/assets/pics/%s" % [DownloadManager.uuid, GameManager.pic_list[card_name]])
func set_pos(x: int, y: int) -> void:
$Sprite.position = Vector2(x, y)
func get_pos() -> Vector2:
return $Sprite.position
+5 -4
View File
@@ -1,22 +1,22 @@
extends Node2D
var CardScene = preload("res://scenes/game/card.tscn")
var card_list: Array
func _ready() -> void:
init()
GameLoopManager.start_game()
var card = create_card("Oxygen")
card.show()
card.set_pos(300, 300)
print(card.get_pos())
func init() -> void:
# 设置 UI 展示文本
if multiplayer.is_server():
$IsServerLabel.text = "GAMEUI_URHOST"
else:
$IsServerLabel.text = "GAMEUI_URGUEST"
var addresses: PackedStringArray = IP.get_local_addresses()
var ipaddress: String = ""
for address in addresses:
@@ -26,8 +26,9 @@ func init() -> void:
$IPLabel.text = ipaddress
$Player1/Username.text = GameManager.username
func create_card(card_name: String):
var card = CardScene.instantiate()
var card = SceneManager.Card.instantiate()
add_child(card)
card.set_card(card_name)
card_list.append(card)
+2 -2
View File
@@ -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:
+1 -1
View File
@@ -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")
+3
View File
@@ -4,11 +4,14 @@ extends Node2D
func _on_join_game_pressed() -> void:
$JoinGameUI.show()
func _on_start_game_pressed() -> void:
$CreateGameUI.show()
func _on_setting_button_pressed() -> void:
SceneManager.goto_scene("menus/settings")
func _on_quit_game_pressed() -> void:
get_tree().quit()
+4 -1
View File
@@ -1,20 +1,24 @@
extends Node2D
func _ready() -> void:
init_sources()
init_text()
func init_text() -> void:
$DataSetting/LineEdit.text = GameManager.data_origin
$IPBeginSetting/LineEdit.text = GameManager.ip_begin
$UsernameSetting/LineEdit.text = GameManager.username
$LoadSource/ChooseSource.select(GameManager.source)
func init_sources() -> void:
DownloadManager.get_sources()
for source_name in GameManager.sources:
$LoadSource/ChooseSource.add_item(source_name)
func _on_save_button_pressed() -> void:
GameManager.data_origin = $DataSetting/LineEdit.text
GameManager.ip_begin = $IPBeginSetting/LineEdit.text
@@ -42,7 +46,6 @@ func _on_download_button_pressed() -> void:
$Tips.text = "SETTINGS_TIP_LOADED"
func _on_load_button_pressed() -> void:
if GameManager.sources.size() == 0 or GameManager.source == -1:
$Tips.text = "SETTINGS_TIP_NOLOCALSOURCE"