feat(settings): Implementiere modulares Einstellungsmenü und Fenstermanagement

- Erstellung des `SettingsManager` als Autoload zur zentralen Verwaltung der Anzeigeeinstellungen.
- Implementierung der `OptionsMenu`-UI mit Dropdown (Auflösung) und CheckBox (Vollbild).
- Anwendung von Separation of Concerns: Strikte Trennung von grafischer Oberfläche und Hintergrundlogik.
- Behebung fehlerhafter Szenen-Abhängigkeiten und fehlerhafter Node-Pfade (Null-Referenzen).
- Umstellung der Logik auf `get_window()`, um die Kompatibilität mit Embedded Subwindows in Godot 4 sicherzustellen.
This commit is contained in:
LeFix 2026-07-04 19:20:52 +02:00
parent a035b749e5
commit 3d88f03ae9
8 changed files with 103 additions and 4 deletions

View File

@ -14,10 +14,12 @@ config/name="Pong v1"
run/main_scene="uid://bbjstb404m82i" run/main_scene="uid://bbjstb404m82i"
config/features=PackedStringArray("4.7", "GL Compatibility") config/features=PackedStringArray("4.7", "GL Compatibility")
[autoload]
SettingsManager="*uid://cq40er6phlcvk"
[display] [display]
window/size/window_width_override=4608
window/size/window_height_override=2592
window/stretch/mode="canvas_items" window/stretch/mode="canvas_items"
[file_customization] [file_customization]

View File

@ -21,6 +21,16 @@ script = ExtResource("1_qr3af")
ball = NodePath("Ball") ball = NodePath("Ball")
score_label = NodePath("ScoreLabel") score_label = NodePath("ScoreLabel")
[node name="OptionsMenu" type="LinkButton" parent="." unique_id=1620714612]
offset_left = 15.0
offset_top = 17.0
offset_right = 88.0
offset_bottom = 57.0
text = "Optionen"
[node name="Camera2D" type="Camera2D" parent="." unique_id=966032468]
position = Vector2(576, 324)
[node name="Ball" type="CharacterBody2D" parent="." unique_id=1987649111] [node name="Ball" type="CharacterBody2D" parent="." unique_id=1987649111]
position = Vector2(576, 324) position = Vector2(576, 324)
scale = Vector2(2, 2) scale = Vector2(2, 2)
@ -68,5 +78,4 @@ theme_override_font_sizes/font_size = 36
text = "Punkt!" text = "Punkt!"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="Camera2D" type="Camera2D" parent="." unique_id=966032468] [connection signal="pressed" from="OptionsMenu" to="." method="_on_options_menu_pressed"]
position = Vector2(576, 324)

36
scene/options_menu.tscn Normal file
View File

@ -0,0 +1,36 @@
[gd_scene format=3 uid="uid://dag530gb7ejhj"]
[ext_resource type="Script" uid="uid://dlxbk5ya2wfxk" path="res://scripts/options_menu.gd" id="1_23fbr"]
[node name="SettingsManager" type="Control" unique_id=1891033022]
layout_mode = 3
anchors_preset = 0
offset_top = 24.0
offset_right = 1152.0
offset_bottom = 24.0
script = ExtResource("1_23fbr")
[node name="settings" type="LinkButton" parent="." unique_id=1104305876]
layout_mode = 0
offset_left = 576.0
offset_top = 324.0
offset_right = 652.0
offset_bottom = 364.0
text = "Zum Spiel"
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1366878422]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="FullscreenCheckButton" type="CheckBox" parent="VBoxContainer" unique_id=1435770377]
layout_mode = 2
text = "Vollbild"
[node name="ResolutionOptionButton" type="OptionButton" parent="VBoxContainer" unique_id=531315819]
layout_mode = 2
[connection signal="pressed" from="settings" to="." method="_on_settings_pressed"]

View File

@ -28,3 +28,7 @@ func _process(_delta: float) -> void:
func update_score_display() -> void: func update_score_display() -> void:
if score_label: if score_label:
score_label.text = str(score_links) + " : " + str(score_rechts) score_label.text = str(score_links) + " : " + str(score_rechts)
func _on_options_menu_pressed() -> void:
get_tree().change_scene_to_file("uid://dag530gb7ejhj")

View File

@ -0,0 +1,20 @@
# settings_manager.gd (Autoload)
extends Node
func set_fullscreen(is_fullscreen: bool) -> void:
var window: Window = get_window()
if is_fullscreen:
window.mode = Window.MODE_FULLSCREEN
else:
window.mode = Window.MODE_WINDOWED
func set_resolution(width: int, height: int) -> void:
var window: Window = get_window()
# Setzt die neue Größe
window.size = Vector2i(width, height)
# Optional aber empfohlen für eine gute User Experience:
# Zentriert das Fenster nach der Größenänderung auf dem Monitor
window.move_to_center()

View File

@ -0,0 +1 @@
uid://cq40er6phlcvk

26
scripts/options_menu.gd Normal file
View File

@ -0,0 +1,26 @@
# options_menu.gd (Nur an den Control-Knoten anhängen!)
extends Control
@onready var fullscreen_toggle: CheckBox = $VBoxContainer/FullscreenCheckButton
@onready var resolution_dropdown: OptionButton = $VBoxContainer/ResolutionOptionButton
func _ready() -> void:
# Dropdown-Werte initialisieren
resolution_dropdown.add_item("1920x1080", 0)
resolution_dropdown.add_item("1280x720", 1)
# Signale verbinden
resolution_dropdown.item_selected.connect(_on_resolution_selected)
fullscreen_toggle.toggled.connect(_on_fullscreen_toggled)
func _on_fullscreen_toggled(button_pressed: bool) -> void:
# Delegation der Aufgabe an den Autoload
SettingsManager.set_fullscreen(button_pressed)
func _on_resolution_selected(index: int) -> void:
match index:
0: SettingsManager.set_resolution(1920, 1080)
1: SettingsManager.set_resolution(1280, 720)
func _on_settings_pressed() -> void:
get_tree().change_scene_to_file("uid://bbjstb404m82i")

View File

@ -0,0 +1 @@
uid://dlxbk5ya2wfxk