Játékmenet

A Godot Engine alapjai - I. Pong
2021-06-06 · 22:53
A legtöbb modern fejlesztőezköz jelentősen megkönnyíti a játékok készítését, nincs ez másként a Godot Engine esetében sem, így minimális kód hozzáadásával bírhatjuk működésre első játékunkat.


Előkészület


Mielőtt elkezdenénk megírni a kódot, be kell állítanunk néhány dolgot. Nyissuk meg a Project Settings ablakot, majd fent váltsunk át az Input Map fülre. Az Action mezőbe írjuk be, hogy "bal_fel", majd nyomjunk [Enter]-t. Ez meg fog jelenni a lista legalján. Kattintsunk a mellette lévő + gombra, majd válasszuk a Key lehetőséget, a felugró ablakban nyomjuk meg a [W] billentyűt, majd kattintsunk az Ok gombra.

Hasonló módon hozzuk létre a "bal_le" bejegyzést, majd adjuk hozzá az [S] billentyűt. Ezután jöhet a "jobb_fel" és a "jobb_le", hozzájuk adva a felfelé illetve a lefelé mutató kurzorbillentyűket. Ezekkel a gombokkal fogjuk irányítani a bal és a jobb oldali ütőt.

A játékunk annyiból fog állni, hogy elindítás után egy másodperccel kilövi a labdát valamelyik irányba, majd a játékosoknak vissza kell azt ütniük. Amint valamelyik játékos elér öt pontot, a játék kiírja, hogy ki nyert majd három másodperc múlva kezdődik elölről.


Ütők mozgatása


Nyissuk meg az Uto scene-t (a csapó ikonra kattintva vagy fent kiválasztva a hozzá tartozó tabot) és kattintsunk jobb egérgombbal az Uto node-ra, majd válasszuk az Attach Script lehetőséget. A Template listából válasszuk az Empty-t, majd kattintsunk az Ok gombra.

extends KinematicBody2D

# milyen gyorsan mozogjon az ütő (pixel/másodperc)
var sebesseg = 600

# _physics_precess(delta) fix időközönként fut le,
# így mozgáshoz érdemes ezt használni
# a "delta" biztosítja, hogy az ütő fix sebességgel mozogjon függetlenül attól,
# hogy 60 vagy 200 fps-sel fut a játék
func _physics_process(delta):
    # ha a node neve BalUto
    if name == "BalUto":
        # ha le van nyomva a gomb, amit a "bal_fel"-nek megadtunk
        if Input.is_action_pressed("bal_fel"):
            # mozduljon el az ütő felfelé, az adott sebességgel
            move_and_collide(Vector2.UP * sebesseg * delta)
		
        # ha le van nyomva a gomb, amit a "bal_le"-nek megadtunk
        if Input.is_action_pressed("bal_le"):
            # mozduljon el az ütő lefelé, az adott sebességgel
            move_and_collide(Vector2.DOWN * sebesseg * delta)

    # ha a node neve JobbUto
    if name == "JobbUto":
        # ha le van nyomva a gomb, amit a "jobb_fel"-nek megadtunk
        if Input.is_action_pressed("jobb_fel"):
        # mozduljon el az ütő felfelé, az adott sebességgel
            move_and_collide(Vector2.UP * sebesseg * delta)
		
        # ha le van nyomva a gomb, amit a "jobb_le"-nek megadtunk
        if Input.is_action_pressed("jobb_le"):
            # mozduljon el az ütő lefelé, az adott sebességgel
            move_and_collide(Vector2.DOWN * sebesseg * delta)


Labda mozgatása


Nyissuk meg a Labda scene-t, majd jobb nyissuk meg a Physics Material Override-ot és adjunk hozzá egy New PhysicsMaterial-t. Erre azért van szükség, hogy a labda vissza tudjon pattanni az ütőkről és a falról. Állítsuk a Friction-t 0-ra (nem lesz súrlódás, tehát nem fog veszíteni a sebességéből), a Bounce-t pedig 1-re (tökéletes lepattanás, azaz ilyenkor sem veszít a sebességéből).

Ezután az Uto-hoz hasonlóan adjunk egy script-et a Labda-hoz is:

extends RigidBody2D

# milyen gyorsan mozogjon a labda (pixel/másodperc)
export var sebesseg = 600


func _ready():
    # véletlenszám generátor indítása
    randomize()

    # labda középre helyezése
    global_position = Vector2(640, 360)

    # egy másodperc várakozás, majd a labda indítása
    yield(get_tree().create_timer(1.0), "timeout")
    indulj()


# labda indítása
func indulj():
    # irány megadása, mely csak 1 és -1 lehet
    # a pow(szam1, szam2) a szam1-et a szam2 hatványra emeli
    # a randi() % 2 egy véletlenszámot generál, melynek értéke 0 vagy 1 lehet
    # minden szám 0. hatványa 1, első hatvány pedig önmaga
    # így kapjuk meg a fent említett 1-et és -1-et
    var x_irany = pow(-1, randi() % 2)
    var y_irany = pow(-1, randi() % 2)
	
    # irány és sebesség megadása
    linear_velocity = Vector2(x_irany, y_irany) * sebesseg


Pontszerzés


Nyissuk meg a Palya scene-t, jelöljük ki a BalKapu-t, majd a jobb oldalon a Collision mezőben vegyük ki a jelölést az első négyzetből, a másodikat viszont jelöljük be. Ezután adjunk egy script-et a Palya node-hoz.

extends Node2D

# készítünk egy hivatkozást a Kijelzo nevű node-ra
onready var Kijelzo = $Kijelzo
# előtöltjük a Labda scene-t,
# hogy játék közben új példányokat hozhassunk létre belőle
var labda_scene = preload("res://Labda.tscn")

# a játékosok pontszáma
var bal_pont = 0
var jobb_pont = 0

# a győzelemhez szükséges pontszám
# a const értéke állandó, nem változhat a játék során
const gyozelem_pont = 5


func _ready():
    # a játék kezdetekor létrehozunk egy példányt a labdából
    var Labda = labda_scene.instance()
    # ez a példány a Palya node child node-ja lesz
    add_child(Labda)


# ha a labda bekerül a bal oldali kapuba
func _on_BalKapu_body_entered(body):
    # a jobb oldali játékos kap egy pontot
    jobb_pont += 1
    # töröljük a labdát
    body.queue_free()
    # hívjuk a pont ellenörző függvényt
    pont_ellenorzes(jobb_pont, "A JOBB OLDALI JÁTÉKOS NYERT!")


# ha a labda bekerül a jobb oldali kapuba
func _on_JobbKapu_body_entered(body):
    # a bal oldali játékos kap egy pontot
    bal_pont += 1
    # töröljük a labdát
    body.queue_free()
    # hívjuk a pont ellenörző függvényt
    pont_ellenorzes(bal_pont, "A BAL OLDALI JÁTÉKOS NYERT!")


# pont ellenörző függvény
# hívásakor az "oldal_pont" és a "szoveg" helyére saját értéket adhatunk
func pont_ellenorzes(oldal_pont, szoveg):
    # a függvényhíváskor megadott saját értéket (pl.: bal_pont)
    # fogja ide behelyettesíteni
    # ha az az érték még nem éri el a győzelemhez szükséges értéket
    if oldal_pont < gyozelem_pont:
        # akkor létrehozunk egy új labda példányt
        var Labda = labda_scene.instance()
        # megvárjuk, hogy az adott frame befejeződjön,
        # majd a labda példányt a Palya-hoz adjuk child node-ként
        call_deferred("add_child", Labda)
        # frissítjük a kijelzőt az aktuális eredménnyel
        Kijelzo.text = str(bal_pont) + " - " + str(jobb_pont)
    # különben pedig
    else:
        # a kijelző szövegét arra a szövegre változtatjuk,
        # amit fent a "szoveg" helyére beírtunk függvényhíváskor
        Kijelzo.text = szoveg
        # várunk 3 másodpercet
        yield(get_tree().create_timer(3.0), "timeout")
        # majd újra betöltjük az aktuális scene-t, így új játékot indítva
        get_tree().reload_current_scene()

Ezzel el is érkeztünk sorozatunk első részének a végéhez. Immár van egy (egyszerű) saját készítésű játékod. Gratulálok!

Azt ajánlom, hogy ne kezdj rögtön a következő részbe, hanem próbáld meg módosítgatni ezt a játékot (készíts azért egy biztonsági mentést róla, hogy legyen hova visszatérni). Változtasd az ütők vagy a labda sebességét/méretét/színét/stb. Megcsinálhatod azt is, hogy az ütők nem a pálya két oldalán, hanem fent és lent vannak, vagy akár a pálya mind a 4 szélén. Kísérletezz bátran! :)