Naucz się programować tworząc gry – GDScript kompleksowy poradnik

# Game
extends Node

var background: Panel
@onready var centerContainer: CenterContainer = CenterContainer.new()
@onready var mainContainer: VBoxContainer = VBoxContainer.new()
@onready var row1: HBoxContainer = HBoxContainer.new()
@onready var row2: HBoxContainer = HBoxContainer.new()
@onready var row3: HBoxContainer = HBoxContainer.new()

var nextSignX: bool = true
var buttons: Array[OurButton] = []
var game_over: bool = false

# Called when the node enters the scene tree for the first time.
func _ready():
	background = Panel.new()
	background.set_anchors_preset(Control.PRESET_FULL_RECT)
	background.set_self_modulate(Color(1,0,0))
	add_child(background)
	
	generate_buttons()
	
	mainContainer.add_child(row1);
	mainContainer.add_child(row2);
	mainContainer.add_child(row3);
	centerContainer.add_child(mainContainer);
	centerContainer.set_anchors_preset(Control.PRESET_FULL_RECT)
	add_child(centerContainer);

func generate_buttons():
	for i in range(9):
		var new_button: Button = OurButton.new()
		new_button.pressed.connect(on_click.bind(new_button))
		buttons.append(new_button)
		
		if i < 3:
			row1.add_child(new_button)
		elif i < 6:
			row2.add_child(new_button)
		else:
			row3.add_child(new_button)

func on_click(button: Button):
	if button.text != "" or game_over:
		return
	if nextSignX:
		button.text = "X"
	else:
		button.text = "O"
	if check_win():
		handle_win()
	if check_draw():
		restart()
	nextSignX = !nextSignX

func wait(seconds: float) -> void:
	await get_tree().create_timer(seconds).timeout

func restart():
	game_over = true
	await wait(1)
	get_tree().reload_current_scene()

func handle_win():
	var winLabel: Label = Label.new()
	winLabel.text = "X win" if nextSignX else "O win"
	winLabel.add_theme_font_size_override("font_size", 64)
	add_child(winLabel)
	restart()

func check_draw():
	for button in buttons:
		if button.text == "":
			return false
	return true

func check_win():
	if buttons[0].text == buttons[1].text and buttons[1].text == buttons[2].text and buttons[0].text != "" :
		return true
	if buttons[3].text == buttons[4].text and buttons[4].text == buttons[5].text and buttons[3].text != "":
		return true
	if buttons[6].text == buttons[7].text and buttons[7].text == buttons[8].text and buttons[6].text != "":
		return true
	if buttons[0].text == buttons[3].text and buttons[3].text == buttons[6].text and buttons[0].text != "":
		return true
	if buttons[1].text == buttons[4].text and buttons[4].text  == buttons[7].text and buttons[1].text != "":
		return true
	if buttons[2].text == buttons[5].text and buttons[5].text  == buttons[8].text and buttons[2].text != "":
		return true
	if buttons[0].text == buttons[4].text and buttons[4].text == buttons[8].text and buttons[0].text != "":
		return true
	if buttons[2].text == buttons[4].text and buttons[4].text == buttons[6].text and buttons[2].text != "":
		return true
	return false

# OurButton
extends Button

class_name OurButton

# Called when the node enters the scene tree for the first time.
func _ready():
	set_self_modulate(Color(0,1,0))
	custom_minimum_size = Vector2(190,190)
	add_theme_font_size_override("font_size", 64)