Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Heads up display

Posledním kouskem, který naše hra potřebuje, je UI: rozhraní pro zobrazování věcí, jako je skóre, zpráva „konec hry“ a tlačítko restartu.

Create a new scene, click the "Other Node" button and add a CanvasLayer node named HUD. "HUD" stands for "heads-up display", an informational display that appears as an overlay on top of the game view.

Uzel CanvasLayer umožňuje nakreslit naše prvky uživatelského rozhraní do vrstvy nad zbytkem hry, takže informace, které zobrazuje, nejsou zakryty žádnými herními prvky, jako je hráč nebo nepřátelé.

HUD musí zobrazit následující informace:

  • Skóre, změněno uzlem ScoreTimer.

  • Zprávu, například „Game Over“ nebo „Připravte se!“

  • Tlačítko "Start" pro zahájení hry.

Základní uzel pro prvky uživatelského rozhraní je Control. K vytvoření našeho uživatelského rozhraní použijeme dva typy Control nodes: Label a Button.

Jako podřízené uzlu HUD vytvořte následující:

  • Label s názvem ScoreLabel.

  • Label pojmenovaný Message.

  • Button s názvem StartButton.

  • Timer s názvem MessageTimer.

Klikněte na ScoreLabel a zadejte číslo do pole Text v Inspektoru. Výchozí písmo pro uzly Control je malé a neškáluje se dobře. Ve herníchzdrojích je obsažen soubor s názvem „Xolonium-Regular.ttf“. Chcete-li použít toto písmo, proveďte následující:

Under "Theme Overrides > Fonts", choose "Load" and select the "Xolonium-Regular.ttf" file.

../../_images/custom_font_load_font.webp

The font size is still too small, increase it to 64 under "Theme Overrides > Font Sizes". Once you've done this with the ScoreLabel, repeat the changes for the Message and StartButton nodes.

../../_images/custom_font_size.webp

Poznámka

Anchors: Control nodes have a position and size, but they also have anchors. Anchors define the origin - the reference point for the edges of the node.

Arrange the nodes as shown below. You can drag the nodes to place them manually, or for more precise placement, use "Anchor Presets".

../../_images/ui_anchor.webp

ScoreLabel

  1. Add the text 0.

  2. Set the "Horizontal Alignment" and "Vertical Alignment" to Center.

  3. Choose the "Anchor Preset" Center Top.

Zpráva

  1. Add the text Dodge the Creeps!.

  2. Set the "Horizontal Alignment" and "Vertical Alignment" to Center.

  3. Set the "Autowrap Mode" to Word, otherwise the label will stay on one line.

  4. Under "Control - Layout/Transform" set "Size X" to 480 to use the entire width of the screen.

  5. Choose the "Anchor Preset" Center.

StartButton

  1. Add the text Start.

  2. Under "Control - Layout/Transform", set "Size X" to 200 and "Size Y" to 100 to add a little bit more padding between the border and text.

  3. Choose the "Anchor Preset" Center Bottom.

  4. Under "Control - Layout/Transform", set "Position Y" to 580.

V MessageTimer nastavte Wait Time na 2 a nastavte vlastnost One Shot na On.

Nyní přidejte tento skript do HUD:

extends CanvasLayer

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

We now want to display a message temporarily, such as "Get Ready", so we add the following code

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

We also need to process what happens when the player loses. The code below will show "Game Over" for 2 seconds, then return to the title screen and, after a brief pause, show the "Start" button.

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()

Tato funkce se volá, když hráč prohraje. Na 2 sekundy se zobrazí „Game Over“, poté se vratíme na titulní obrazovku a po krátké pauze se zobrazí tlačítko „Start“.

Poznámka

Pokud potřebujete pozastavit na krátkou dobu, alternativou k použití uzlu Timer je použití funkce create_timer() třídy SceneTree. To může být velmi užitečné pro přidání zpoždění, jako například ve výše uvedeném kódu, kdy chceme počkat, než se zobrazí tlačítko „Start“.

Add the code below to HUD to update the score

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

Connect the timeout() signal of MessageTimer and the pressed() signal of StartButton, and add the following code to the new functions:

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

func _on_message_timer_timeout():
    $Message.hide()

Připojení HUD k Main

Nyní, když jsme dokončili scénu HUD, vraťte se ke scéně Main. Vytvořte instanci scény HUD ve Main, jak jste to udělali se scénou Player. Strom scény by měl vypadat takto, takže se ujistětě, že vám něco neuniklo:

../../_images/completed_main_scene.webp

Nyní musíme propojit funkcionalitu HUD se skriptem Main. To vyžaduje několik přídavků ke scéně Main:

In the Node tab, connect the HUD's start_game signal to the new_game() function of the Main node by clicking the "Pick" button in the "Connect a Signal" window and selecting the new_game() method or type "new_game" below "Receiver Method" in the window. Verify that the green connection icon now appears next to func new_game() in the script.

V new_game() aktualizujte zobrazení skóre a zobrazte zprávu „Připravte se“:

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

V game_over() musíme zavolat odpovídající HUD` funkci:

$HUD.show_game_over()

Finally, add this to _on_score_timer_timeout() to keep the display in sync with the changing score:

$HUD.update_score(score)

Varování

Remember to remove the call to new_game() from _ready() if you haven't already, otherwise your game will start automatically.

Now you're ready to play! Click the "Play the Project" button. You will be asked to select a main scene, so choose main.tscn.

Odstranění starých nepřátel

Pokud budete hrát až do „Game Over“ a ihned poté zahájíte novou hru, můžou se na obrazovce stále zobrazovat nepřátelé z předchozí hry. Bylo by lepší, kdyby všichni zmizeli na začátku hry nové. Potřebujeme jen způsob, jak říct všem nepřátelům, aby zmizeli. Můžeme to udělat pomocí funkcionality „skupina“.

Ve scéně Mob vyberte kořenový uzel a klikněte na kartu "Uzel" vedle Inspektoru (na stejném místě, kde najdete signály uzlu). Vedle položky "Signály" klikněte na "Skupiny" a můžete zadat nový název skupiny a kliknout na tlačítko "Přidat".

../../_images/group_tab.webp

Nyní budou všechny nepřátelé ve skupině „mobs“. K funkci game_over() v Main pak můžeme přidat následující řádek:

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

Funkce call_group() volá pojmenovanou funkci na každém uzlu ve skupině - v tomto případě říkáme každému nepříteli, aby se sám odstranil.

The game's mostly done at this point. In the next and last part, we'll polish it a bit by adding a background, looping music, and some keyboard shortcuts.