Vytváření her ve 2D

Tahák ve formě webové stránky

Rozcestník:

Area2D
CharacterBody2D
Funkce
Podmínka if

Node

Area2D

Area2D se používá jako objekt, který kontroluje, když do něj něco vstoupí. Typicky se využívá pro různé hitboxy, čudlíky, atd.. Praktické využití si můžeme představit například u vystřelené kulky ze zbraně. Když zjistí, že se dotkla hráče (přelínají se jejich CollisionShape-y), tak hráčovi zašle signál, že byl zasažen.
Je důležité rozlišovat mezi Nodema ve skupině "Body" a "Area". Pokud zašleme signál "_on_area2d_body_entered", ale snažíme se najít node, který je Area2D, nebude to fungovat.

Signály

On area entered - Spustí se, když do našeho Area2D vstoupí další Area2D.
On area extied - Spustí se, když z našeho Area2D odejde jiný Area2D.
On body entered - Nejčastější signál, spustí se, když do našeho Area2D vstoupí Body Node, tedy například CharacterBody2D, StaticBody2D, RigidBody2D, atd.

Ukázka kódu:

extends Area2D

func _on_area2d_body_entered(body):
    if body.is_in_group("hrac"): # Pokud je body, který právě vstoupil, ve skupině "hrac"...
        body.queue_free() # Smaž body (pro více info klikněte na queue_free() )

CharacterBody2D

CharacterBody2D je Node, který se typicky využívá pro hráče.
Rozdíl od ostatních Node je takový, že při přídání CollisionShape2D nemusíme ještě přidávat StaticBody2D, aby se objekt stal pevným, tedy nemohl procházet skrz zdi.
Ostatní rozdíly si momentálně nepamatuji, ale je všeobecně dobrý nápad využívat tento Node pro většinu hráčů, krom pár vyjímek.

Ukázka kódu:

extends CharacterBody2D

var gravitace = 200 # Říkáme kódu, že kdykoliv, když napíšeme "gravitace", myslíme tím tuto hodnotu, tedy 200.

func _physics_process(delta):
     velocity.x = 0 # Pokud se nic nemačká, nepohybuj se na ose x (doprava a doleva).
     velocity.y += gravitace # Pokud se nic nemačká, nepohybuj se na ose x (doprava a doleva).

    if Input.is_action_pressed("ui_right"): # Pokud je zmáčknuto tlačítko "ui_right" (doprava)...
        velocity.x = 200 # Pohybuj se na ose x o 200

    move_and_slide() # Umožňuje, aby se v této funkci užívalo velocity a ostatní užitečné věci, které si teď nepamatuji. Ve "_physics_process()" toto zásadně nesmí chybět!

Funkce:

Rozcestník:

_physics_process(delta)
is_action_just_pressed()
is_action_pressed()

Funkce jsou části kódu, které se spustí, když jsou zavolány. Spustit je můžem buďto my, v kódu, nebo se mohou spoušťět samy.
Důležité je také rozlišit mezi předem definovanými a námi vytvořenými funkcemi. Předem definované, například is_action_pressed() budou fungovat, aniž bychom museli cokoliv jiného dělat. Pokud ale si chceme vytvořit vlastní funkci, musíme si jí definovat.
Zde je příklad:

func ahoj(): # Zde říkáme, že jsme si vytvořili funkci. Cokoliv co bude napsáno v ní, se spustí kdykoliv, kdy funkci tzv. "zavoláme".
    print("ahoj")

Pokud tedy funkci potom zavoláme:

if Input.is_action_just_pressed("ui_up"): # Je-li zmáčknutý mezérník/enter/atd. ...
    ahoj() # Spustí se funkce ahoj(), kterou jsme si již definovali. Vypíše se tedy do konzole "ahoj".

_physics_process(delta)

Pro pohyb hráče využíváme funkci "_physics_process(delta)". Vypádá takto:

extends CharacterBody2D

func _physics_process(delta):

    velocity.x = 0 # Rychlost na ose x (doprava a doleva) je 0. Tudíž bude, alespoň v této ose, stát na místě.

    move_and_slide() # Umožňuje, aby se v této funkci užívalo velocity a ostatní užitečné věci, které si teď nepamatuji. Ve "_physics_process()" toto zásadně nesmí chybět!

Funkce "_physics_process(delta)" nám umožňuje používat "velocity" a "move_and_slide()", oboje nutnosti pro pohyb.

Cokoliv co je psáno v této funkci, se bude opakovat každý snímek, tedy typicky 60 za sekundu. (Pokud se počítač seká, může se toto číslo zmenšit. Tímto se hra zpomalí. Lze toto obejí pomocí tzv. "delty", ale tu prozatím nebudeme využívat). Tímto se podobá funkci "_process()", která také spustí svůj kód každý snímek, ale nevyužívá se pro ovládání hráče.

is_action_just_pressed()

Funkce "is_action_just_pressed()" nám umožňuje kontrolovat, zda je zmáčknutá klávesa. Danou klávesu píšeme do závorek této funkce. Oproti is_action_pressed()se nebude kód pod touto (typicky) podmínkou opakovat, ale spustí se pouze jednou.

if Input.is_action_just_pressed("ui_up"): # Je-li zmáčknutý mezérník/enter/atd. ...
    jump() # V tomto kódu se spustí funkce "jump()". Pro objasnění, funkce "jump()" není automaticky definovaná, což znamená, že bychom si jí museli vytvořit my.

is_action_pressed()

Funkce "is_action_pressed()" nám umožňuje kontrolovat, zda je zmáčknutá klávesa. Danou klávesu píšeme do závorek této funkce. Oproti is_action_just_pressed()se bude kód pod touto (typicky) podmínkou opakovat, dokud klávesu nepustíme.

if Input.is_action_pressed("ui_accept"): # Je-li zmáčknutý mezérník/enter/atd. ...
    velocity.x = 200 # Rychlost na ose x (doprava a doleva) je 200. Tudíž se bude node pohybovat vpravo.

queue_free()

Smaže objekt, u kterého je tato funkce zavolána.

Ukázka kódu:

if Input.is_action_pressed("ui_accept"): # Je-li zmáčknutý mezérník/enter/atd. ...
    get_node("Pepa").queue_free() # Smaž objekt Pepa

Podmínka if

"if" se používá, pokud chceme spustit kód pouze pokud je splněna určitá podmínka.

Ukázka:

if 1 == 1: # Pokud 1 = 1...
    print("ahoj") # Vypiš do konzole "ahoj"

Pozor!

Při psaní if podmínek je velice důležité, aby byla instrukce, kterou chceme vykonat při splnění podmínky, napsaná s odrážkou (tabulátorem).

Ukázka správného zapsání podmínky if:

if neco == true: # Pokud "neco" má přiřazenou hodnotu "true"...
    objekt.nevim() # Spusť u "objekt" funkci "nevim"

Ukázka špatného zapsání podmínky if:

if beham == true: # Pokud "beham" má přiřazenou hodnotu "true"...
tohleje.spatne() # Spusť u "tohleje" funkci "spatne"