238 lines
6.1 KiB
GDScript
238 lines
6.1 KiB
GDScript
extends CanvasLayer
|
|
## Startmenü: Einzelspieler, Mehrspieler (Host/Client mit Lobby), Beenden.
|
|
|
|
const BOT_NAMES_MAX := 7
|
|
|
|
var screens: Dictionary = {}
|
|
|
|
# Einzelspieler
|
|
var solo_bots: SpinBox
|
|
|
|
# Mehrspieler
|
|
var name_edit: LineEdit
|
|
var ip_edit: LineEdit
|
|
var multi_bots: SpinBox
|
|
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:
|
|
var root := Control.new()
|
|
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
add_child(root)
|
|
|
|
var bg := ColorRect.new()
|
|
bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
bg.color = Color(0.05, 0.06, 0.09)
|
|
root.add_child(bg)
|
|
|
|
screens["main"] = _screen(root, _build_main())
|
|
screens["single"] = _screen(root, _build_single())
|
|
screens["multi"] = _screen(root, _build_multi())
|
|
|
|
Net.lobby_changed.connect(_refresh)
|
|
Net.connection_failed.connect(_on_failed)
|
|
Net.server_closed.connect(_on_closed)
|
|
_show("main")
|
|
|
|
|
|
# ------------------------------------------------------------ Aufbau
|
|
|
|
func _screen(root: Control, content: Control) -> CenterContainer:
|
|
var cc := CenterContainer.new()
|
|
cc.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
cc.add_child(content)
|
|
root.add_child(cc)
|
|
return cc
|
|
|
|
|
|
func _show(which: String) -> void:
|
|
for key: String in screens:
|
|
screens[key].visible = key == which
|
|
if which == "multi":
|
|
_refresh()
|
|
|
|
|
|
func _box(width: int) -> VBoxContainer:
|
|
var v := VBoxContainer.new()
|
|
v.custom_minimum_size = Vector2(width, 0)
|
|
v.add_theme_constant_override("separation", 10)
|
|
return v
|
|
|
|
|
|
func _text(t: String, size: int, col := Color.WHITE) -> Label:
|
|
var l := Label.new()
|
|
l.text = t
|
|
l.add_theme_font_size_override("font_size", size)
|
|
l.add_theme_color_override("font_color", col)
|
|
l.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
return l
|
|
|
|
|
|
func _row(caption: String, ctrl: Control) -> HBoxContainer:
|
|
var h := HBoxContainer.new()
|
|
var l := Label.new()
|
|
l.text = caption
|
|
l.custom_minimum_size = Vector2(150, 0)
|
|
h.add_child(l)
|
|
ctrl.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
h.add_child(ctrl)
|
|
return h
|
|
|
|
|
|
func _button(text: String, parent: Control, action: Callable) -> Button:
|
|
var b := Button.new()
|
|
b.text = text
|
|
b.custom_minimum_size = Vector2(0, 42)
|
|
b.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
b.pressed.connect(action)
|
|
parent.add_child(b)
|
|
return b
|
|
|
|
|
|
func _title(box: VBoxContainer) -> void:
|
|
box.add_child(_text("LIAR'S DICE 3D", 40))
|
|
box.add_child(_text("Würfeln - Bluffen - Boostern", 16, Color(0.6, 0.63, 0.7)))
|
|
box.add_child(HSeparator.new())
|
|
|
|
|
|
func _build_main() -> Control:
|
|
var box := _box(360)
|
|
_title(box)
|
|
_button("Einzelspieler", box, _show.bind("single"))
|
|
_button("Mehrspieler", box, _show.bind("multi"))
|
|
_button("Beenden", box, func() -> void: get_tree().quit())
|
|
return box
|
|
|
|
|
|
func _build_single() -> Control:
|
|
var box := _box(400)
|
|
_title(box)
|
|
box.add_child(_text("Einzelspieler", 22, Color(1.0, 0.82, 0.32)))
|
|
solo_bots = SpinBox.new()
|
|
solo_bots.min_value = 1
|
|
solo_bots.max_value = BOT_NAMES_MAX
|
|
solo_bots.value = 3
|
|
box.add_child(_row("Bots", solo_bots))
|
|
box.add_child(_text("Ohne Netzwerk - du spielst allein gegen die Bots.", 13, Color(0.55, 0.58, 0.65)))
|
|
box.add_child(HSeparator.new())
|
|
var row := HBoxContainer.new()
|
|
row.add_theme_constant_override("separation", 8)
|
|
box.add_child(row)
|
|
_button("Starten", row, _on_solo_start)
|
|
_button("Zurück", row, _show.bind("main"))
|
|
return box
|
|
|
|
|
|
func _build_multi() -> Control:
|
|
var box := _box(440)
|
|
_title(box)
|
|
box.add_child(_text("Mehrspieler", 22, Color(1.0, 0.82, 0.32)))
|
|
|
|
name_edit = LineEdit.new()
|
|
name_edit.text = "Spieler"
|
|
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))
|
|
|
|
multi_bots = SpinBox.new()
|
|
multi_bots.min_value = 0
|
|
multi_bots.max_value = BOT_NAMES_MAX
|
|
multi_bots.value = 1
|
|
box.add_child(_row("Bots (nur Host)", 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)
|
|
|
|
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))
|
|
box.add_child(lobby_list)
|
|
|
|
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)
|
|
|
|
_button("Zurück", box, _on_back)
|
|
status = _text("", 14, Color(0.95, 0.55, 0.5))
|
|
box.add_child(status)
|
|
return box
|
|
|
|
|
|
# ------------------------------------------------------------ Aktionen
|
|
|
|
func _on_solo_start() -> void:
|
|
Net.start_singleplayer("Spieler", int(solo_bots.value))
|
|
|
|
|
|
func _on_host() -> void:
|
|
status.text = ""
|
|
if Net.host_game(name_edit.text.strip_edges()):
|
|
status.text = "Server läuft auf Port %d. Warte auf Mitspieler." % Net.PORT
|
|
|
|
|
|
func _on_join() -> void:
|
|
status.text = "Verbinde..."
|
|
Net.join_game(ip_edit.text.strip_edges(), name_edit.text.strip_edges())
|
|
|
|
|
|
func _on_leave() -> void:
|
|
Net.leave()
|
|
status.text = ""
|
|
|
|
|
|
func _on_back() -> void:
|
|
if Net.is_online():
|
|
Net.leave()
|
|
status.text = ""
|
|
_show("main")
|
|
|
|
|
|
func _on_start() -> void:
|
|
var humans: int = Net.lobby.size()
|
|
var ai: int = mini(int(multi_bots.value), Net.MAX_HUMANS - humans)
|
|
if humans + ai < 2:
|
|
status.text = "Mindestens 2 Spieler nötig (Mitspieler oder Bots)."
|
|
return
|
|
Net.start_game(ai)
|
|
|
|
|
|
func _on_failed(msg: String) -> void:
|
|
status.text = msg
|
|
_refresh()
|
|
|
|
|
|
func _on_closed() -> void:
|
|
status.text = "Server hat die Verbindung beendet."
|
|
_refresh()
|
|
|
|
|
|
func _refresh() -> void:
|
|
if status == 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)
|
|
multi_bots.editable = not connected or Net.is_host
|
|
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)
|