update
This commit is contained in:
192
scripts/menu.gd
192
scripts/menu.gd
@@ -1,23 +1,25 @@
|
||||
extends CanvasLayer
|
||||
## Startmenü: Einzelspieler, Mehrspieler (Host/Client mit Lobby), Beenden.
|
||||
## Startmenü: Einzelspieler, Mehrspieler (hosten oder per Code beitreten),
|
||||
## Lobby und Beenden.
|
||||
|
||||
const BOT_NAMES_MAX := 7
|
||||
|
||||
var screens: Dictionary = {}
|
||||
var status_labels: Dictionary = {}
|
||||
var current := "main"
|
||||
|
||||
# Einzelspieler
|
||||
var solo_bots: NumberRow
|
||||
|
||||
# Mehrspieler
|
||||
var name_edit: LineEdit
|
||||
var ip_edit: LineEdit
|
||||
var multi_bots: NumberRow
|
||||
var code_edit: LineEdit
|
||||
|
||||
# Lobby
|
||||
var lobby_bots: NumberRow
|
||||
var code_label: Label
|
||||
var lobby_list: Label
|
||||
var status: Label
|
||||
var host_btn: Button
|
||||
var join_btn: Button
|
||||
var start_btn: Button
|
||||
var leave_btn: Button
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -33,6 +35,8 @@ func _ready() -> void:
|
||||
screens["main"] = _screen(root, _build_main())
|
||||
screens["single"] = _screen(root, _build_single())
|
||||
screens["multi"] = _screen(root, _build_multi())
|
||||
screens["join"] = _screen(root, _build_join())
|
||||
screens["lobby"] = _screen(root, _build_lobby())
|
||||
|
||||
Net.lobby_changed.connect(_refresh)
|
||||
Net.connection_failed.connect(_on_failed)
|
||||
@@ -51,12 +55,20 @@ func _screen(root: Control, content: Control) -> CenterContainer:
|
||||
|
||||
|
||||
func _show(which: String) -> void:
|
||||
current = which
|
||||
for key: String in screens:
|
||||
screens[key].visible = key == which
|
||||
if which == "multi":
|
||||
_sagen("")
|
||||
if which == "lobby":
|
||||
_refresh()
|
||||
|
||||
|
||||
## Meldungen gehören auf den Bildschirm, auf dem man gerade steht.
|
||||
func _sagen(text: String) -> void:
|
||||
for key: String in status_labels:
|
||||
status_labels[key].text = text if key == current else ""
|
||||
|
||||
|
||||
func _box(width: int) -> VBoxContainer:
|
||||
var v := VBoxContainer.new()
|
||||
v.custom_minimum_size = Vector2(width, 0)
|
||||
@@ -94,6 +106,13 @@ func _button(text: String, parent: Control, action: Callable) -> Button:
|
||||
return b
|
||||
|
||||
|
||||
## Eine Zeile für Meldungen, unten auf jedem Bildschirm.
|
||||
func _status_row(box: VBoxContainer, key: String) -> void:
|
||||
var l := _text("", 14, Color(0.95, 0.55, 0.5))
|
||||
box.add_child(l)
|
||||
status_labels[key] = l
|
||||
|
||||
|
||||
## Eine Reihe anklickbarer Zahlen - bei so wenigen Werten schneller als eine
|
||||
## Spinbox mit ihren winzigen Pfeilen.
|
||||
class NumberRow extends HBoxContainer:
|
||||
@@ -120,17 +139,14 @@ class NumberRow extends HBoxContainer:
|
||||
for i in _buttons.size():
|
||||
_buttons[i].button_pressed = _lo + i == n
|
||||
|
||||
## Werte oberhalb von `hi` sperren (im Mehrspieler sind die Plätze begrenzt).
|
||||
func set_limit(hi: int) -> void:
|
||||
## Obergrenze und Bedienbarkeit in einem Zug - getrennt würde der eine
|
||||
## Aufruf den anderen wieder aufheben.
|
||||
func anpassen(hi: int, on: bool) -> void:
|
||||
for i in _buttons.size():
|
||||
_buttons[i].disabled = _lo + i > hi
|
||||
_buttons[i].disabled = not on or _lo + i > hi
|
||||
if value > hi:
|
||||
pick(maxi(_lo, hi))
|
||||
|
||||
func set_enabled(on: bool) -> void:
|
||||
for b in _buttons:
|
||||
b.disabled = not on
|
||||
|
||||
|
||||
func _title(box: VBoxContainer) -> void:
|
||||
box.add_child(_text("LIAR'S DICE 3D", 40))
|
||||
@@ -162,6 +178,7 @@ func _build_single() -> Control:
|
||||
return box
|
||||
|
||||
|
||||
## Erster Schritt: nur der Name, dann hosten oder beitreten.
|
||||
func _build_multi() -> Control:
|
||||
var box := _box(440)
|
||||
_title(box)
|
||||
@@ -172,34 +189,68 @@ func _build_multi() -> Control:
|
||||
name_edit.placeholder_text = "Dein Name"
|
||||
box.add_child(_row("Name", name_edit))
|
||||
|
||||
ip_edit = LineEdit.new()
|
||||
ip_edit.text = "127.0.0.1"
|
||||
box.add_child(_row("Server-IP", ip_edit))
|
||||
|
||||
box.add_child(_text("Bots (nur Host)", 15))
|
||||
multi_bots = NumberRow.new(0, BOT_NAMES_MAX, 1)
|
||||
box.add_child(multi_bots)
|
||||
|
||||
var brow := HBoxContainer.new()
|
||||
brow.add_theme_constant_override("separation", 8)
|
||||
box.add_child(brow)
|
||||
host_btn = _button("Spiel hosten", brow, _on_host)
|
||||
join_btn = _button("Beitreten", brow, _on_join)
|
||||
_button("Hosten", brow, _on_host)
|
||||
_button("Beitreten", brow, _show.bind("join"))
|
||||
|
||||
_button("Zurück", box, _show.bind("main"))
|
||||
_status_row(box, "multi")
|
||||
return box
|
||||
|
||||
|
||||
## Zweiter Schritt beim Beitreten: der Code vom Host.
|
||||
func _build_join() -> Control:
|
||||
var box := _box(440)
|
||||
_title(box)
|
||||
box.add_child(_text("Beitreten", 22, Color(1.0, 0.82, 0.32)))
|
||||
box.add_child(_text("Den Code bekommst du vom Host.", 15,
|
||||
Color(0.65, 0.67, 0.72)))
|
||||
|
||||
code_edit = LineEdit.new()
|
||||
code_edit.placeholder_text = "z. B. K7QM"
|
||||
code_edit.max_length = 6
|
||||
code_edit.alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
code_edit.add_theme_font_size_override("font_size", 24)
|
||||
code_edit.text_submitted.connect(func(_t: String) -> void: _on_join())
|
||||
box.add_child(code_edit)
|
||||
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 8)
|
||||
box.add_child(row)
|
||||
_button("Beitreten", row, _on_join)
|
||||
_button("Zurück", row, _show.bind("multi"))
|
||||
_status_row(box, "join")
|
||||
return box
|
||||
|
||||
|
||||
## Dritter Schritt: warten, bis alle da sind.
|
||||
func _build_lobby() -> Control:
|
||||
var box := _box(440)
|
||||
_title(box)
|
||||
box.add_child(_text("Lobby", 22, Color(1.0, 0.82, 0.32)))
|
||||
|
||||
code_label = _text("", 34, Color(1.0, 0.82, 0.32))
|
||||
box.add_child(code_label)
|
||||
box.add_child(_text("Diesen Code an die Mitspieler geben.", 14,
|
||||
Color(0.65, 0.67, 0.72)))
|
||||
box.add_child(HSeparator.new())
|
||||
box.add_child(_text("Lobby", 18, Color(1.0, 0.82, 0.32)))
|
||||
lobby_list = _text("-", 15, Color(0.85, 0.87, 0.92))
|
||||
|
||||
lobby_list = _text("-", 16, Color(0.85, 0.87, 0.92))
|
||||
box.add_child(lobby_list)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
var arow := HBoxContainer.new()
|
||||
arow.add_theme_constant_override("separation", 8)
|
||||
box.add_child(arow)
|
||||
start_btn = _button("Spiel starten", arow, _on_start)
|
||||
leave_btn = _button("Trennen", arow, _on_leave)
|
||||
box.add_child(_text("Bots", 15))
|
||||
lobby_bots = NumberRow.new(0, BOT_NAMES_MAX, 1)
|
||||
box.add_child(lobby_bots)
|
||||
|
||||
_button("Zurück", box, _on_back)
|
||||
status = _text("", 14, Color(0.95, 0.55, 0.5))
|
||||
box.add_child(status)
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 8)
|
||||
box.add_child(row)
|
||||
start_btn = _button("Spiel starten", row, _on_start)
|
||||
_button("Verlassen", row, _on_leave)
|
||||
_status_row(box, "lobby")
|
||||
return box
|
||||
|
||||
|
||||
@@ -216,66 +267,57 @@ func _spielername() -> String:
|
||||
|
||||
|
||||
func _on_host() -> void:
|
||||
status.text = ""
|
||||
if Net.host_game(_spielername()):
|
||||
status.text = "Server läuft auf Port %d. Warte auf Mitspieler." % Net.PORT
|
||||
_refresh()
|
||||
_sagen("Raum wird angelegt ...")
|
||||
Net.create_room(_spielername())
|
||||
|
||||
|
||||
func _on_join() -> void:
|
||||
status.text = "Verbinde..."
|
||||
Net.join_game(ip_edit.text.strip_edges(), _spielername())
|
||||
_refresh()
|
||||
_sagen("Verbinde ...")
|
||||
Net.join_room(code_edit.text, _spielername())
|
||||
|
||||
|
||||
func _on_leave() -> void:
|
||||
Net.leave()
|
||||
status.text = ""
|
||||
|
||||
|
||||
func _on_back() -> void:
|
||||
if Net.is_online():
|
||||
Net.leave()
|
||||
status.text = ""
|
||||
_show("main")
|
||||
_show("multi")
|
||||
|
||||
|
||||
func _on_start() -> void:
|
||||
var humans: int = Net.lobby.size()
|
||||
var ai: int = mini(multi_bots.value, Net.MAX_HUMANS - humans)
|
||||
var ai: int = mini(lobby_bots.value, Net.MAX_HUMANS - humans)
|
||||
if humans + ai < 2:
|
||||
status.text = "Mindestens 2 Spieler nötig (Mitspieler oder Bots)."
|
||||
_sagen("Mindestens 2 Spieler nötig (Mitspieler oder Bots).")
|
||||
return
|
||||
Net.start_game(ai)
|
||||
Net.request_start(ai)
|
||||
|
||||
|
||||
func _on_failed(msg: String) -> void:
|
||||
status.text = msg
|
||||
_refresh()
|
||||
_sagen(msg)
|
||||
|
||||
|
||||
func _on_closed() -> void:
|
||||
status.text = "Server hat die Verbindung beendet."
|
||||
_refresh()
|
||||
_show("multi")
|
||||
_sagen("Der Raum wurde geschlossen.")
|
||||
|
||||
|
||||
## Sobald der Server uns kennt, sind wir in der Lobby.
|
||||
func _refresh() -> void:
|
||||
if status == null:
|
||||
if lobby_list == null:
|
||||
return
|
||||
var connected := Net.is_online()
|
||||
host_btn.disabled = connected
|
||||
join_btn.disabled = connected
|
||||
leave_btn.disabled = not connected
|
||||
start_btn.disabled = not (connected and Net.is_host)
|
||||
if not connected or not Net.is_host:
|
||||
multi_bots.set_enabled(not connected)
|
||||
else:
|
||||
multi_bots.set_enabled(true)
|
||||
multi_bots.set_limit(Net.MAX_HUMANS - Net.lobby.size())
|
||||
if Net.lobby.is_empty():
|
||||
lobby_list.text = "- nicht verbunden -"
|
||||
else:
|
||||
var names: Array = []
|
||||
for id: int in Net.lobby:
|
||||
names.append("%s%s" % [Net.lobby[id], " (Host)" if id == 1 else ""])
|
||||
lobby_list.text = "\n".join(names)
|
||||
var drin := Net.is_online() and Net.lobby.has(multiplayer.get_unique_id())
|
||||
if drin and current != "lobby":
|
||||
_show("lobby")
|
||||
elif not drin and current == "lobby":
|
||||
_show("multi")
|
||||
if current != "lobby":
|
||||
return
|
||||
|
||||
code_label.text = Net.room_code
|
||||
start_btn.disabled = not Net.is_owner
|
||||
lobby_bots.anpassen(Net.MAX_HUMANS - Net.lobby.size(), Net.is_owner)
|
||||
|
||||
var names: Array = []
|
||||
for id: int in Net.lobby:
|
||||
names.append("%s%s" % [Net.lobby[id], " (Host)" if id == Net.owner_id else ""])
|
||||
lobby_list.text = "\n".join(names)
|
||||
if not Net.is_owner:
|
||||
_sagen("Der Host startet die Partie.")
|
||||
|
||||
Reference in New Issue
Block a user