Kijelzők szerkesztése és mentés

A Godot Engine alapjai - II. Arkanoid · sztrovacsek

A játékunk már a jelenlegi formájában is játszható, de pár aprósággal még javíthatunk rajta.


Labda szerkesztése


Először is el fogjuk tüntetni a labdát, ha az adott pályán eltűnt az összes tégla. Nyissuk meg a PalyaSablon script-et és adjuk hozzá a következő pár sort:

extends Node2D

# létrehozunk egy új signal-t
signal labda_torles

[...]

func _process(delta):
    if $Teglak.get_child_count() == 0:
        # elküldjük a signal-t
        emit_signal("labda_torles")
        $Kijelzok/Kozep.visible = true
        if Kovetkezo == null:
            $Kijelzok/Kozep/Gombok/Folytatas.disabled = true

Ezután nyissuk meg a Labda script-et és kössük be az előbb elküldött signal-t:

func _ready():
    position = Vector2(640, 580)
    # kapcsolódunk a signal-hoz
    get_parent().connect("labda_torles", self, "_on_PalyaSablon_labda_torles")


func _on_PalyaSablon_labda_torles():
    # megállítjuk a labdát
    linear_velocity = Vector2.ZERO
    # és kikapcsoljuk a láthatóságát
    visible = false

Egyszerűen törölhettük is volna, a megállítás és rejtés helyett, de akkor csak azt értük volna el, hogy egy újabb labdát hoz létre a gép. Így viszont tanultunk egy új módszert.


Meglévő labdák kijelzése


Észrevehettük már, hogy hiába van a kijelzőn csak 3 labdánk, azok soha nem fogynak el. Javítsunk hát ezen.

Script nézetben hozzunk létre egy új script-et - File -> New Script - és nevezzük el "Global.gd"-nek. Adjuk hozzá az alábbi pár sort:

extends Node

var rekord = 0
var pont = 0
var elet = 3

var teljes_kepernyo = false
var hang = true

var Labda

Ezután Project -> Project Settings... és válasszuk fent az AutoLoad fület. Itt a Path mezőbe tallózzuk be a Global.gd fájlt. Ezután kattintsunk jobb oldalon az Add gombra aztán bezárhatjuk. Így egy olyan script-et hoztunk létre, amit bárhonnan elérhetünk, és akkor sem törlődnek az értékei, ha scene-t váltunk, így tökéletes a pontszám és a hátralévő labdák számának a tárolására.

Nyissuk meg ismét a Labda script-et és módosítsuk az alábbiak szerint:

func _ready():
    # a labda létrehozásakor eltároljuk azt a Global script-ben
    # így arra is hivatkozunk bárhonnan a nevét használva
    Global.Labda = self
    [...]

func _physics_process(delta):
    if position.y > 720:
        labda_torles()

func labda_torles():
    # kivonunk 1-et a Global script elet nevű változójából
    Global.elet -= 1
    queue_free()

Nyissuk meg a Bomba scene-t és adjunk hozzá egy script-et, amibe bekötjük a body_entered() signal-t:

# ha a Bomba ütközött
func _on_Bomba_body_entered(body):
    # hívjuk a Labda-n a labda_torles() függvényt
    Global.Labda.labda_torles()
    # töröljük a bombát
    queue_free()

Ezután nyissuk meg a PalyaSablon script-et:

func labda_letrehozasa():
    # hozzá rendelünk dolgokat a Global elet változójának érékéhez
    match Global.elet:
        # ha 2
        2:
            # a 3. labda átlátszóságát levesszük 10%-ra
            # azért van a zárójelben 2, mert 0-tól indul a számozás
            $Kijelzok/Jobb/Golyo/Ikonok.get_child(2).modulate.a = .1
        # ha 1
        1:
            # a 2. labda átlátszóságát is levesszük 10%-ra
            $Kijelzok/Jobb/Golyo/Ikonok.get_child(1).modulate.a = .1
        # ha 0
        0:
            # az 1. labda átlátszóságát is levesszük 10%-ra
            $Kijelzok/Jobb/Golyo/Ikonok.get_child(0).modulate.a = .1
        # ha -1
        -1:
            # visszaáálítjuk az életet 3-ra
            Global.elet = 3
            # elmentjük a rekordot a Global script-be
            Global.rekord = rekord
            # visszatérünk a főmenübe
            get_tree().change_scene("res://Menu.tscn")

    var Labda = labda_scene.instance()
    call_deferred("add_child", Labda)


Pontszám kezelése


Továbbra is a PalyaSablon script-ben maradva:

extends Node2D

onready var RekordSzam = $Kijelzok/Bal/RekordSzam
onready var PontSzam = $Kijelzok/Bal/PontSzam
onready var SzorzoSzam = $Kijelzok/Bal/SzorzoSzam
onready var SzorzoAnim = $Kijelzok/Bal/SzorzoSzam/SzorzoAnim

var rekord = 0
var pont = 0
var szorzo = 0
[...]

func _ready():
    # kezdésnél lekérjük a pont értékét a Global scriptből
    pont = Global.pont
    # és meg is jelenítjük azt a kijelzőn
    PontSzam.text = str(pont)
    # a rekord értékét is lekérjük
    rekord = Global.rekord
    # és szintén kiírjuk
    RekordSzam.text = str(rekord)
    labda_letrehozasa()
    # végigfutunk a Teglak node child node-jain
    for Tegla in $Teglak.get_children():
        # és bekötjük mindegyikből a signal-t
        Tegla.connect("pont", self, "_on_Tegla_pont")


# a tégla széttörésekor
func _on_Tegla_pont():
    # növeljük a pontszámot
    pont += 5 * szorzo
    # és ki is írjuk azt
    PontSzam.text = str(pont)
    # ha a rekord kisebb, mint a pontszám
    if rekord < pont:
        # akkor a rekord új érték az adott pontszám lesz
        rekord = pont
        # és ezt ki is írjuk
        RekordSzam.text = str(rekord)


func _on_Folytatas_pressed():
    # mielőtt a következő pályára lépnénk,
    # átmentjük a pontszámot a Global script-be
    Global.pont = pont
    # ha a pontszám nagyobb, mint a Global rekord értéke,
    if Global.rekord < rekord:
        # akkor azt is átmentjük
        Global.rekord = rekord
    get_tree().change_scene_to(Kovetkezo)

Ezzel majdnem meg is vagyunk, de így csak addig lesz elmentve a pontszámunk, míg be nem zárjuk a játékot. Ahhoz, hogy ezután is megmaradjon, nyissuk meg a Global script-et és adjuk hozzá az alábbi sorokat:

# ide lesz létrehozva a mentés fájl
var mentes_utvonal = "res://mentes_file.cfg"
# elkészítjük a mentés fájlt
var mentes_file = ConfigFile.new()
# betöltjük a mentés file-t
var mentes_file_betolto = mentes_file.load(mentes_utvonal)pontpont


# mentés függvény
func mentes(section, key):
    # megadjuk, hogy mit mentsen el a file
    mentes_file.set_value("pontszam", "rekord", rekord)
    # elmentjük a fájlt a megadott útvonalra
    mentes_file.save(mentes_utvonal)


# betöltés függvény
func betoltes(section, key):
    # betöltjük és megadjuk értéknek a mentés fájlból kiolvasott értéket
    rekord = mentes_file.get_value("pontszam", "rekord", rekord)


Ezután nyissuk meg újra a PalyaSablon script-et és hívjuk meg benne az előbb létrehozott függvényeket:

func _ready():
	Global.betoltes("pontszam", "rekord")
[...]


func rekord_mentes():
    if Global.rekord < rekord:
        Global.rekord = rekord
        Global.mentes("pontszam", "rekord")


func _process(delta):
    if Input.is_action_just_pressed("ui_cancel"):
        rekord_mentes()
        Global.pont = 0
    [...]


func labda_letrehozasa():
    match Global.elet:
        [...]
        -1:
            Global.elet = 3
            Global.pont = 0
            rekord_mentes()
    [...]

func _on_Folytatas_pressed():
    Global.pont = pont
    rekord_mentes()
    get_tree().change_scene_to(Kovetkezo)

func _on_Kilepes_pressed():
    Global.pont = 0
    rekord_mentes()
    get_tree().change_scene("res://Menu.tscn")


Beállítások mentése


Hasonló módon menthetjük el a beállításokat is, először is nyissuk meg a BeallitasokMenu script-et és módosítsuk a következők szerint:

extends Control


func _ready():
    # ha teljes képernyőn van a játék, előre bepipáljuk a négyzetet,
    # ha nincs, akkor pedig kivesszük a pipát
    $Gombok/TeljesKepernyo.pressed = true if OS.window_fullscreen else false
    # ha engedélyezve van a hang, előre bepipáljuk a négyzetet,
    # ha nincs, akkor pedig kivesszük a pipát
    $Gombok/Hangok.pressed = true if Global.hang == true else false


# ha rákattintunk a hangok jelölőnégyzetre
func _on_Hangok_pressed():
    # engedélyezzük a hangot, ha ki van pipálva,
    # különben pedig nem
    var hang = true if $Gombok/Hangok.pressed else false
    # lenémítjuk az AudioServert, attól függően, hogy engedélyezve van-e a hang
    # a ! a hang előtt a tagadást jelzi, mivel a függvény a némításra vonatkozik,
    # azaz, ha VAN hang, akkor NINCS némítás
    AudioServer.set_bus_mute(0, !hang)
    # átadjuk a hang értékét a Global script-nek
    Global.hang = hang
    # elmentjük a hang értékét
    Global.mentes("beallitasok", "hang")


func _on_TeljesKepernyo_pressed():
    # engedélyezzük a teljes képernyőt, ha ki van pipálva,
    # különben pedig nem
    OS.window_fullscreen = true if $Gombok/TeljesKepernyo.pressed else false
    # átadjuk a teljes képernyő értékét a Global script-nek
    Global.teljes_kepernyo = OS.window_fullscreen
    # elmentjük a teljes képernyő értékét
    Global.mentes("beallitasok", "teljes_kepernyo")

[...]

Térjünk vissza a Global script-re és adjuk hozzá a beállításokat is a mentendő adatokhoz:

func mentes(section, key):
    mentes_file.set_value("pontszam", "rekord", rekord)
    mentes_file.set_value("beallitasok", "teljes_kepernyo", teljes_kepernyo)
    mentes_file.set_value("beallitasok", "hang", hang)
    mentes_file.save(mentes_utvonal)


func betoltes(section, key):
    rekord = mentes_file.get_value("pontszam", "rekord", rekord)
    teljes_kepernyo = mentes_file.get_value("beallitasok", "teljes_kepernyo", teljes_kepernyo)
    hang = mentes_file.get_value("beallitasok", "hang", hang)

Végül nyissuk meg a Menu script-et is, hogy a beállítások rögtön betöltődjenek, ahogy elindítjuk a játékot:

func _ready():
    Global.betoltes("beallitasok", "teljes_kepernyo")
    OS.window_fullscreen = Global.teljes_kepernyo
    Global.betoltes("beallitasok", "hang")
    AudioServer.set_bus_mute(0, !Global.hang)

Ha elindítjuk a játékot és mókolunk a menüben, illetve ha játék közben elfogy az életünk, akkor láthatjuk, hogy a játék könyvtárában létrejött egy mentes_file.cfg nevű fájl, amit ha megnyitunk, akkor láthatjuk, hogy valóban ott vannak benne az adatok, amiket elmentettünk:

[pontszam]

rekord=65

[beallitasok]

teljes_kepernyo=false
hang=true

A mentéseket általában nem ajánlott egy sima szövegfájlban tárolni, ebben a leckében csak az egyszerűség kedvéért csináltuk így. A sorozat harmadik részében megnézzük majd, hogy tudjuk titkosítani a mentett fájlokat.