extends Control # Spieler-Definitionen const PLAYER_X = "X" const PLAYER_O = "O" const EMPTY = "" var current_player = PLAYER_X var game_over = false # Referenzen zu den Nodes @onready var board_grid = $Board @onready var status_label = $StatusLabel @onready var win_line = $WinLine # Mapping von Numpad-Aktionen zu den Array-Indizes (0 bis 8) var numpad_mapping = { "pad_7": 0, "pad_8": 1, "pad_9": 2, "pad_4": 3, "pad_5": 4, "pad_6": 5, "pad_1": 6, "pad_2": 7, "pad_3": 8 } var buttons = [] # --- NEU: Beide Textur-Referenzen geladen --- var circle_texture = load("res://res/Dornenkrone.png") # Textur für O var cross_texture = load("res://res/Rankenkreuz.png") # Textur für X (Hier Pfad anpassen!) # -------------------------------------------- var win_conditions = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] func _ready(): board_grid.custom_minimum_size = Vector2(500, 500) buttons = board_grid.get_children() win_line.clear_points() for i in range(buttons.size()): buttons[i].size_flags_horizontal = Control.SIZE_EXPAND_FILL buttons[i].size_flags_vertical = Control.SIZE_EXPAND_FILL # Buttons komplett leeren (kein störender Text mehr) buttons[i].text = EMPTY # Finde die TextureRect-Node im Button und leere sie für den Start var piece_texture = buttons[i].get_node("PieceTexture") piece_texture.texture = null buttons[i].pressed.connect(_on_button_pressed.bind(i)) update_status_label() func _input(event): if game_over: return for action in numpad_mapping.keys(): if event.is_action_pressed(action): var index = numpad_mapping[action] var piece_texture = buttons[index].get_node("PieceTexture") if piece_texture.texture == null: make_move(index) func _on_button_pressed(index): var piece_texture = buttons[index].get_node("PieceTexture") if game_over or piece_texture.texture != null: return make_move(index) func make_move(index): var piece_texture = buttons[index].get_node("PieceTexture") # Weist jetzt je nach Spieler die korrekte Bild-Textur zu if current_player == PLAYER_O: piece_texture.texture = circle_texture else: piece_texture.texture = cross_texture var winning_combo = check_win() if winning_combo != null: status_label.text = "Spieler " + current_player + " hat gewonnen!" game_over = true animate_win_line(winning_combo) elif check_draw(): status_label.text = "Unentschieden!" game_over = true else: current_player = PLAYER_O if current_player == PLAYER_X else PLAYER_X update_status_label() func update_status_label(): status_label.text = "Spieler " + current_player + " ist am Zug." # Prüft den Gewinn vollautomatisch über die gesetzten Texturen func check_win(): for cond in win_conditions: var p0 = buttons[cond[0]].get_node("PieceTexture").texture var p1 = buttons[cond[1]].get_node("PieceTexture").texture var p2 = buttons[cond[2]].get_node("PieceTexture").texture if current_player == PLAYER_O: if p0 == circle_texture and p1 == circle_texture and p2 == circle_texture: return cond else: if p0 == cross_texture and p1 == cross_texture and p2 == cross_texture: return cond return null # Prüft auf Unentschieden: Wenn alle Felder eine Textur haben, ist das Feld voll func check_draw() -> bool: for button in buttons: var piece_texture = button.get_node("PieceTexture") if piece_texture.texture == null: return false return true func get_button_center(button: Button) -> Vector2: return button.global_position + (button.size / 2) func animate_win_line(combo: Array): var start_pos = get_button_center(buttons[combo[0]]) var end_pos = get_button_center(buttons[combo[2]]) var direction = (end_pos - start_pos).normalized() var padding = 40.0 var extended_start = start_pos - (direction * padding) var extended_end = end_pos + (direction * padding) win_line.clear_points() win_line.add_point(extended_start) win_line.add_point(extended_start) var tween = create_tween() tween.tween_method( func(pos): win_line.set_point_position(1, pos), extended_start, extended_end, 0.4 ).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)