Groups: veel nodes tegelijk aansturen
Je hebt nu meerdere muntjes en misschien een paar vijanden in je level. Maar hoe spreek je ze allemaal tegelijk aan — bijvoorbeeld om te tellen hoeveel muntjes er nog over zijn, of om alle vijanden in één keer te laten stoppen? Daarvoor gebruik je groups.
Geschreven voor Godot 4.7.x — zie Godot-versies voor compatibiliteit.
Voorspel: alle muntjes tellen
Stel je wilt weten hoeveel muntjes er nog in je level staan. Hoe zou je dat aanpakken met wat je tot nu toe kent?
Antwoord
Je zou elk muntje met de hand kunnen opzoeken via get_node(...) en ze tellen. Maar dan moet je elke naam kennen, en het klopt niet meer zodra je een muntje toevoegt of weghaalt. Een group lost dit op: je geeft elk muntje hetzelfde label en vraagt Godot daarna gewoon "geef me alles met dat label".
Wat is een group?
Een group is een label dat je op een node plakt. Meerdere nodes mogen hetzelfde label dragen. Daarna kun je in één regel:
- alle nodes met dat label ophalen (en bijvoorbeeld tellen);
- op alle nodes met dat label tegelijk een functie aanroepen.
Het mooie: de nodes hoeven niets van elkaar te weten — net als bij signals is het lekker ontkoppeld.
Stap 1: Zet je muntjes in een group
Dit kan op twee manieren. Kies er één.
In de editor:
- Selecteer je
Muntje-node. - Ga naar het Node-tabblad (rechts, naast de Inspector) en klik op Groups.
- Typ
muntjesen klik op Add.
Of in code — zet dit in het script van het muntje, zodat elk muntje zichzelf bij het opstarten in de group zet:
extends Area2D
func _ready() -> void:
add_to_group("muntjes")
Doe hetzelfde voor je vijanden met het label vijanden.
Stap 2: Alle muntjes ophalen en tellen
Met get_tree().get_nodes_in_group("muntjes") krijg je een lijst van alle nodes in de group. De lengte daarvan is het aantal muntjes:
var aantal = get_tree().get_nodes_in_group("muntjes").size()
print("Er zijn nog ", aantal, " muntjes.")
| Code | Wat doet het? |
|---|---|
get_tree() | Geeft toegang tot de hele scène-boom |
get_nodes_in_group("muntjes") | De lijst met alle nodes in de group muntjes |
.size() | Hoeveel het er zijn |
Stap 3: Een functie op de hele group aanroepen
Met call_group roep je dezelfde functie aan op elke node in de group. Stel je vijand-script heeft een functie stop():
get_tree().call_group("vijanden", "stop")
Elke node in de group vijanden voert nu zijn eigen stop()-functie uit — handig om bijvoorbeeld alle vijanden te bevriezen als de speler wint.
Opdracht 6.5.a: win als alle muntjes weg zijn
Laat in Uitvoer "Je hebt gewonnen!" verschijnen zodra de speler het laatste muntje oppakt.
queue_free() verwijdert een node pas aan het einde van het frame. Het zojuist opgepakte muntje zit dus nog even in de group. Tel daarom op <= 1 in plaats van == 0.
Klik hier voor een tip.
Breid het muntje-script uit _on_body_entered uit. Vraag ná queue_free() hoeveel muntjes er nog in de group muntjes zitten, en print je winst-bericht als dat er nog maar één is (het muntje dat net wordt opgeruimd).
Klik hier voor de oplossing.
extends Area2D
func _ready() -> void:
add_to_group("muntjes")
func _on_body_entered(body: Node2D) -> void:
queue_free()
if get_tree().get_nodes_in_group("muntjes").size() <= 1:
print("Je hebt gewonnen!")
Het laatste muntje wordt wel queue_free()'d, maar telt in dit frame nog mee — daarom <= 1.
Opdracht 6.5.b: laat alle vijanden stoppen
Geef je vijanden het label vijanden en een functie stop() die de vijand op zijn plek laat staan (bijvoorbeeld door een print of door beweging uit te zetten). Roep stop() op alle vijanden tegelijk aan zodra de speler wint.
Klik hier voor een tip.
Zet de vijand in de group met add_to_group("vijanden") in _ready(). Gebruik op het moment van winnen get_tree().call_group("vijanden", "stop").
Klik hier voor de oplossing.
In het vijand-script:
extends Area2D
func _ready() -> void:
add_to_group("vijanden")
func stop() -> void:
print("Vijand gestopt!")
Op het moment dat de speler wint (bijvoorbeeld in het muntje-script):
get_tree().call_group("vijanden", "stop")
Er gaat iets mis
Mijn group is altijd leeg / get_nodes_in_group geeft 0 terug
Oorzaak: De naam van de group klopt niet exact (groups zijn hoofdlettergevoelig), of de nodes zijn nog niet aan de group toegevoegd.
Oplossing:
- Controleer dat je overal exact dezelfde naam gebruikt, bijvoorbeeld
muntjes(nietMuntjesofmuntje). - Staat
add_to_group(...)in_ready()(en niet in_init())? In_init()bestaat de scène-boom nog niet.
Ik krijg een fout op call_group: de functie bestaat niet
Oorzaak: Niet elke node in de group heeft de aangeroepen functie.
Oplossing: Zorg dat élke node in de group dezelfde functienaam heeft (bijvoorbeeld stop()), of gebruik get_nodes_in_group en controleer per node met has_method("stop") voordat je 'm aanroept.