extends Node2D # L'oggetto scena utilizzato per creare le celle export(PackedScene) var scena_cella export(int) var offset_griglia = 70 enum GIOCATORI {GIOCATORE_1, GIOCATORE_2} var giocatore = GIOCATORI.GIOCATORE_1 var dimensione_finestra:Vector2 var colonne:int var righe:int var stati_precedenti = [] var celle = [] var gioco_finito: bool = false var scaling:float var spaziatura:float var celle_da_cambiare = [] const quadrato_grigio = preload("res://Assets/Texture/grey square.svg") var dimensioni_texture = quadrato_grigio.get_size() var player_1_color = Vector3(0,1,0) var player_2_color = Vector3(1,0,0) # Li carico una volta e sono poi accessibili da tutte le celle """ const quadrato_grigio_1v = preload("res://Assets/Texture/grey square(1g).svg") const quadrato_grigio_2v = preload("res://Assets/Texture/grey square(2g).svg") const quadrato_grigio_3v = preload("res://Assets/Texture/grey square(3g).svg") const quadrato_grigio_1r = preload("res://Assets/Texture/grey square(1r).svg") const quadrato_grigio_2r = preload("res://Assets/Texture/grey square(2r).svg") const quadrato_grigio_3r = preload("res://Assets/Texture/grey square(3r).svg") """ const suono_cella_rossa = preload("res://Assets/Suoni/cell03.wav") const suono_cella_verde = preload("res://Assets/Suoni/cell04.wav") # Comincia la partita func _on_HUD_inizia_gioco() -> void: $HUD.aggiorna_giocatore() # Nascondi la schermata iniziale e mostra chi sta giocando e i bottoni undo ed exit $HUD/Contenitore_verticale.hide() $HUD/Contenitore_alto.show() colonne = $HUD/Contenitore_verticale/Contenitore_centrante/Input_numero_colonne.value # Calcolare lo scaling ci servirà poi per la creazione degli sprite delle esplosioni dimensione_finestra = get_viewport_rect().size scaling = float(dimensione_finestra.x) / colonne / (dimensioni_texture.x) spaziatura = scaling * (dimensioni_texture.x + 1) righe = (dimensione_finestra.y - offset_griglia) / spaziatura $Contenitore_griglia.columns = colonne $Contenitore_griglia.margin_right = dimensione_finestra.x $Contenitore_griglia.margin_bottom = offset_griglia + righe * dimensione_finestra.x / colonne for i in range(colonne * righe): var cella = scena_cella.instance() $Contenitore_griglia.add_child(cella) cella.num = i cella.manager_di_gioco = self var tmp = 4 if i < colonne: tmp -= 1 if i % colonne == 0: tmp -= 1 if (i + 1) % colonne == 0: tmp -= 1 if i > (righe * colonne) - colonne - 1: tmp -= 1 cella.vicini = tmp cella.aggiorna_texture() celle.append(cella) cella.connect("turno_iniziato",self,"_on_turno_iniziato") # Cosa fare quando il giocatore di turno ha cliccato su una cella func _on_turno_iniziato(cella_cambiata) -> void: # All'inizio di ogni turno, salva lo stato di tutte le celle prima che inizi, cosi si puo tornare indietro # Stati inizio turno contiene un array con tutti i valori correnti di [stato, giocatore a cui appartiene] per ogni cella var stati_inizio_turno = [] for i in celle: stati_inizio_turno.append([i.stato,i.giocatore]) # Stati precedenti contiene tutti gli stati_inizio_turno passati stati_precedenti.append(stati_inizio_turno) # Per tenere conto di quali celle cambiare, le metto in un array e quando ho finito il turno size sara 0 celle_da_cambiare.append(cella_cambiata) while celle_da_cambiare.size() > 0: # Ho bisogno di tmp perche devo leggere poi inserire e infine togliere le celle, # tmp contiene le celle da cambiare, mentre cells_to_change verra popolato con nuove celle per la prossima iterazione del while var tmp = celle_da_cambiare celle_da_cambiare = [] # exploding_cells contiene un array di sprite usati per la animazione quando esplodono le celle # Dobbiamo metterli in un array perche cosi una volta che hanno finito la animazione possono essere distrutte var celle_che_esploderanno = [] for i in tmp: # Aumenta lo stato della cella celle[i].giocatore_corrente = giocatore celle[i].aumenta() # Se la cella e esplosa if celle[i].stato == 0: # Controlla i vicini, e aggiungili a quelli che devono aumentare il prossimo turno, # Inoltre crea gli sprite per la animazione, collegandoli a Tween if giocatore == GIOCATORI.GIOCATORE_1: $SFX_di_gioco.stream = suono_cella_verde else: $SFX_di_gioco.stream = suono_cella_rossa $SFX_di_gioco.play() # Controlla in alto if i > colonne - 1: celle_da_cambiare.append(i - colonne) aggiungi_cella_che_esplode(celle_che_esploderanno,i,0,-1) # Controlla a sinistra if i % colonne != 0: celle_da_cambiare.append(i - 1) aggiungi_cella_che_esplode(celle_che_esploderanno,i,-1,0) # Controlla a destra if (i + 1) % colonne != 0: celle_da_cambiare.append(i + 1) aggiungi_cella_che_esplode(celle_che_esploderanno,i,1,0) # Controlla giu if i < (righe * colonne) - colonne: celle_da_cambiare.append(i + colonne) aggiungi_cella_che_esplode(celle_che_esploderanno,i,0,1) # Fai partire tutte le animazioni insieme e aspetta che finiscano (yield) $Tween.start() yield($Tween,"tween_all_completed") # Elimina gli sprite usati per le animazioni for j in celle_che_esploderanno: j.queue_free() celle_che_esploderanno.clear() # E gli indirizzi di quelli che sono stati appena aumentati tmp.clear() # Se qualcuno ha vinto if controlla_vincitore(): # Fai partire un timer per un piccolo delay prima che si torni alla schermata di partenza, e tutto si resetti $Restart_delay.start() if giocatore == GIOCATORI.GIOCATORE_1: $HUD/Contenitore_verticale/Titolo_del_gioco.text = "Vince giocatore 1" else: $HUD/Contenitore_verticale/Titolo_del_gioco.text = "Vince giocatore 2" gioco_finito = true return cambia_giocatore() # Cosa fare quando finisce il timer di delay della fine della partita func _on_Restart_delay_timeout() -> void: game_over() # Cosa fare quando è premuto il bottone undo func _on_HUD_segnale_undo() -> void: # Non fare nulla se non si puo tornare indietro, o se il turno non e finito if stati_precedenti.empty() or !celle_da_cambiare.empty(): return # Ritorna la griglia allo stato precedente cambia_giocatore() var tmp = stati_precedenti.pop_back() var j:int = 0 for i in tmp: celle[j].stato = i[0] celle[j].giocatore = i[1] celle[j].aggiorna_texture() j += 1 # Cosa fare quando è premuto il bottone esci func _on_HUD_segnale_esci(): $HUD/Contenitore_verticale/Titolo_del_gioco.text = "Titolo del gioco" gioco_finito = true game_over() func controlla_vincitore() -> bool: if stati_precedenti.size() < 2: return false for i in celle: if i.stato > 0 and i.giocatore != giocatore: return false return true # Funzione per pulire risorse utilizzate dal gioco che si è appena concluso, e mostrare/nascondere la UI func game_over() -> void: celle_da_cambiare.clear() giocatore = GIOCATORI.GIOCATORE_1 stati_precedenti.clear() $HUD/Contenitore_alto.hide() $HUD/Contenitore_verticale.show() for i in celle: i.queue_free() celle.clear() gioco_finito = false func cambia_giocatore() -> void: match giocatore: GIOCATORI.GIOCATORE_1: giocatore = GIOCATORI.GIOCATORE_2 GIOCATORI.GIOCATORE_2: giocatore = GIOCATORI.GIOCATORE_1 $HUD.aggiorna_giocatore() # Serve così che tutte le celle vuote siano del colore del giocatore di turno for i in celle: if i.stato == 0: i.giocatore = giocatore i.aggiorna_texture() """ const exploding_green = preload("res://Assets/Texture/simple green.svg") const exploding_red = preload("res://Assets/Texture/simple red.svg") """ const materiale_cella_che_esplode = preload("res://Assets/Shaders/Materiale_cella_che_esplode.tres") func aggiungi_cella_che_esplode(celle_che_esplodono,i,x_off,y_off) -> void: var expl = Sprite.new() expl.material = materiale_cella_che_esplode expl.texture = quadrato_grigio expl.scale = Vector2(scaling,scaling) if x_off == -1: expl.rotation = 180 elif y_off == 1: expl.rotation = 90 elif y_off == 1: expl.rotation = -90 expl.scale = Vector2(scaling,scaling) var size = celle[i].rect_size var begin_pos = celle[i].rect_position + size / 2 + Vector2(0,offset_griglia) var end_pos = celle[i + x_off + y_off * colonne].rect_position + size / 2 + Vector2(0,offset_griglia) if giocatore == GIOCATORI.GIOCATORE_1: expl.material.set_shader_param("player",player_1_color) # expl.texture = exploding_green else: expl.material.set_shader_param("player",player_2_color) # expl.texture = exploding_red add_child(expl) # Passa dalla posizione iniziale della cella n. i a quella vicina $Tween.interpolate_property(expl,"position",begin_pos,end_pos,1) celle_che_esplodono.append(expl)