Heads up display (HUD)

L'ultimo pezzo di cui il nostro gioco ha bisogno è un'interfaccia utente (UI) che visualizzi informazioni come il punteggio, un messaggio "game over" e un pulsante per riavviare.

Creare una nuova scena, clicca sul pulsante "Altro nodo" e aggiungi un nodo CanvasLayer denominato HUD. "HUD" sta per "heads-up display", un schermata informativa che appare sovrapposta alla vista di gioco.

Il nodo CanvasLayer ci consente di disegnare i nostri elementi dell'interfaccia utente su un livello sopra il resto del gioco, in modo che le informazioni visualizzate non siano coperte da elementi di gioco come il giocatore o i mob.

L'HUD deve mostrare le seguenti informazioni:

  • Punteggio, modificato da ''ScoreTimer''.

  • Un messaggio, ad esempio "Game Over" o "Get Ready!"

  • Un pulsante "Start" per iniziare il gioco.

Il nodo di base per gli elementi dell'interfaccia utente è Control. Per creare l'interfaccia utente, useremo due tipi di nodi Control: Label e Button.

Crea i seguenti come figli del nodo HUD:

  • Label denominato ScoreLabel.

  • Label denominato Message.

  • Button denominato StartButton.

  • Timer denominato MessageTimer.

Fare clic su ScoreLabel e digitare un numero nel campo Testo nell'Inspector. Il tipo di font predefinito per i nodi Control è piccolo e non scala bene. C'è un file di font incluso nelle risorse di gioco chiamato "Xolonium-Regular.ttf". Per utilizzare questo font, eseguire le operazioni seguenti:

Sotto "Sostituzioni del tema > Font", scegli "Carica" e seleziona il file "Xolonium-Regular.ttf".

../../_images/custom_font_load_font.webp

La dimensione del font è ancora troppo piccola, aumentala a 64 in "Sostituzioni del tema > Dimensioni del font". Dopo aver modificato ScoreLabel, ripeti le modifiche per i nodi Message e StartButton.

../../_images/custom_font_size.webp

Nota

Ancoraggi: I nodi Control hanno una posizione e dimensioni, ma hanno anche ancoraggi. Gli ancoraggi definiscono l'origine, ovvero il punto di riferimento per gli spigoli del nodo.

Organizza i nodi come mostrato in seguito. Puoi trascinare i nodi per posizionarli manualmente o, per un posizionamento più preciso, utilizzare le "preimpostazioni di ancoraggio".

../../_images/ui_anchor.webp

ScoreLabel

  1. Aggiungi il testo 0.

  2. Imposta l'"Allineamento orizzontale" e l'"Allineamento verticale" su Center.

  3. Scegli la "preimpostazione di ancoraggio" Al centro in alto.

Messaggio

  1. Aggiungi il testo Dodge the Creeps!.

  2. Imposta l'"Allineamento orizzontale" e l'"Allineamento verticale" su Center.

  3. Impostare l'"Autowrap Mode" su Word, altrimenti l'etichetta rimarrà su una riga.

  4. In "Control - Layout/Trasform" imposta "Size X" su 480 per utilizzare l'intera larghezza dello schermo.

  5. Scegli la "preimpostazione di ancoraggio" Al centro.

StartButton

  1. Aggiungi il testo Start.

  2. In "Control - Layout/Transform", imposta "Size X" su 200 e "Size Y" su 100 per aggiungere un po' più di spaziatura tra il bordo e il testo.

  3. Scegli la "preimpostazione di ancoraggio" Al centro in basso.

  4. In "Control - Layout/Transform", imposta "Position Y" su 580.

Sul MessageTimer, imposta Tempo d'attesa su 2 e imposta la proprietà Colpo singolo su "On".

Ora aggiungi questo script a ''HUD'':

extends CanvasLayer

# Notifies `Main` node that the button has been pressed
signal start_game

Ora vogliamo visualizzare temporaneamente un messaggio, ad esempio "Get Ready", quindi aggiungiamo il seguente codice

func show_message(text):
    $Message.text = text
    $Message.show()
    $MessageTimer.start()

Dobbiamo anche elaborare cosa succede quando il giocatore perde. Il seguente codice mostrerà "Game Over" per 2 secondi, poi ritornerà alla schermata del titolo e, dopo una breve pausa, mostrerà il pulsante "Start".

func show_game_over():
    show_message("Game Over")
    # Wait until the MessageTimer has counted down.
    await $MessageTimer.timeout

    $Message.text = "Dodge the Creeps!"
    $Message.show()
    # Make a one-shot timer and wait for it to finish.
    await get_tree().create_timer(1.0).timeout
    $StartButton.show()

Nota

Quando è necessario sospendere per un breve periodo di tempo, un'alternativa all'utilizzo di un nodo Timer consiste nell'utilizzare la funzione create_timer() di SceneTree. Questo può essere molto utile per ritardare, come nel codice sopra, dove vogliamo aspettare un po 'di tempo prima di mostrare il pulsante "Start".

Aggiungi il codice seguente a HUD per aggiornare il punteggio

func update_score(score):
    $ScoreLabel.text = str(score)

Collega il segnale pressed() di StartButton e il segnale timeout() di MessageTimer al nodo HUD e aggiungi il seguente codice alle nuove funzioni:

func _on_start_button_pressed():
    $StartButton.hide()
    start_game.emit()

func _on_message_timer_timeout():
    $Message.hide()

Collegamento di HUD a Main

Ora che abbiamo finito di creare la scena HUD, tornare a Main. Istanza la scena HUD in Main come hai fatto per la scena Player. L'albero della scena completo dovrebbe essere simile a questo, quindi assicurati di non aver tralasciato nulla:

../../_images/completed_main_scene.webp

Ora dobbiamo collegare la funzionalità HUD al nostro script Main. Ciò richiede alcune aggiunte alla scena Main:

Nella scheda Node, collega il segnale start_game dell'HUD alla funzione new_game() del nodo Main, cliccando sul pulsante "Scegli" nella finestra "Connetti un segnale" e selezionando il metodo new_game(), oppure digitando "new_game" in "Metodo ricevitore" nella stessa finestra. Verifica che l'icona verde di connessione appaia ora accanto a func new_game() nello script.

In new_game(), aggiorna la visualizzazione del punteggio e mostra il messaggio "Get Ready":

$HUD.update_score(score)
$HUD.show_message("Get Ready")

In game_over() dobbiamo chiamare la corrispondente funzione HUD:

$HUD.show_game_over()

Infine, aggiungi questo a _on_score_timer_timeout() per mantenere la schermata sincronizzata con il punteggio che cambia:

$HUD.update_score(score)

Avvertimento

Ricordati di rimuovere la chiamata a new_game() da _ready() se non lo hai già fatto, altrimenti il tuo gioco partirà automaticamente.

Ora sei pronto per giocare! Clicca sul pulsante "Esegui il progetto".

Rimuovere i vecchi "creeps"

Se giochi fino al "Game Over" e inizi subito una nuova partita, i creeps del gioco precedente potrebbero essere ancora sullo schermo. Sarebbe meglio se scomparissero tutti all'inizio di una nuova partita. Abbiamo solo bisogno di un modo per dire a tutti i mob di sparire. Possiamo farlo con la funzione "gruppo".

Nella scena Mob, seleziona il nodo radice e clicca sulla scheda "Nodo" accanto all'Ispettore (lo stesso posto dove si trovano i segnali del nodo). Accanto a "Segnali", clicca su "Gruppi" per aprire il riepilogo dei gruppi e il pulsante "+" per aprire la finestra di dialogo "Crea un nuovo gruppo".

../../_images/group_tab.webp

Assegna al gruppo il nome mobs e clicca su "ok" per aggiungere un nuovo gruppo di scena.

../../_images/add_group_dialog.webp

Ora tutti i mob saranno nel gruppo "mobs".

../../_images/scene_group_mobs.webp

Possiamo quindi aggiungere la seguente riga alla funzione new_game() in Main:

get_tree().call_group("mobs", "queue_free")

La funzione call_group() chiama la funzione cosi denominata su ogni nodo di un gruppo - cosi facendo diciamo a ogni mob di cancellarsi.

A questo punto il gioco è quasi completato. Nella prossima e ultima parte, lo rifiniremo un po' aggiungendo uno sfondo, musica in ripetizione e alcune scorciatoie da tastiera.