Merge branch 'develop' into 'master'
优化代码,准备重写GameLoopManager.gd See merge request paper-chemis-community/game!7
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
.godot/
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -29,8 +29,8 @@ game/
|
||||
- autoload/
|
||||
- GameManager.gd # 游戏管理
|
||||
- DownloadManager.gd # 下载管理
|
||||
- MultiGame.gd # 多人游戏功能
|
||||
- SceneManager.gd # 场景管理
|
||||
- GameLoopManager.gd # 游戏循环管理
|
||||
- main_menu/
|
||||
- main_menu.gd
|
||||
- join_game_ui.gd
|
||||
@@ -46,6 +46,12 @@ game/
|
||||
|
||||
请先运行数据后端,在游戏设置中输入后端 URL(包含端口号和 `http://` 或 `https://` 前缀),或者选择本地已有的数据源,然后创建游戏或加入游戏开始游玩。
|
||||
|
||||
## 部分游戏逻辑介绍
|
||||
|
||||
### 游戏循环
|
||||
|
||||
游戏循环管理器(GameLoopManager.gd)负责游戏游戏循环的管理。
|
||||
|
||||
## 最佳实践
|
||||
|
||||
本项目目前正在使用 Godot 4.6.2 进行开发。开发用语言为 GDScript。
|
||||
@@ -56,4 +62,4 @@ game/
|
||||
|
||||
- 除连接了信号或 HTTPRequest、MultiplayerAPI 的函数外,任何函数都不应该以下划线(`_`)开头。
|
||||
|
||||
- 函数之间只需间隔一行,无需间隔两行。
|
||||
- 函数之间既可间隔一行,也可间隔两行。建议函数间隔两行,部分间隔一行的函数为遗留问题。
|
||||
|
||||
@@ -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)
|
||||
@@ -0,0 +1 @@
|
||||
uid://dkwc5qney4yee
|
||||
@@ -0,0 +1,5 @@
|
||||
# AI 生成代码文件
|
||||
|
||||
这个目录下的代码都是 AI 生成的,仅作参考。
|
||||
|
||||
不要将本目录下的代码直接复制到被使用的代码处。
|
||||
+1
-1
@@ -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]
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
uid://qxowgxfp4iwm
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 +0,0 @@
|
||||
uid://dwbuaieufg51g
|
||||
@@ -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
|
||||
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
|
||||
var root: Window = get_tree().root
|
||||
current_scene = root.get_child(root.get_child_count() - 1)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user