Score bijhouden in je karakter
Je pakt nu muntjes op, maar je weet niet hoeveel. In deze les voeg je een score toe die elke keer met 1 omhoog gaat als je een muntje raakt.
Predict
Stel je wilt een score bijhouden. In welk script zou je de variabele score aanmaken?
- In het muntje-script?
- In het karakter-script?
- Ergens anders?
Denk er even over na voordat je verder leest.
Bekijk het antwoord
Het muntje is geen goede plek: zodra het muntje wordt opgepakt, verdwijnt het via queue_free() — en daarmee ook zijn score-variabele.
Het karakter is een logische plek: de speler "draagt" zijn eigen score. Zolang het karakter bestaat, blijft de score bestaan.
Stap 1: Voeg score toe aan je karakter
Open het script van je CharacterBody2D en voeg bovenaan een variabele toe:
extends CharacterBody2D
const SPEED = 300.0
const JUMP_VELOCITY = -800.0
var score = 0
# ... rest van je script
Stap 2: Hoog de score op vanuit het muntje
Open het script van je muntje. In _on_body_entered heb je al een parameter body — dat is de node die het muntje aanraakt (jouw karakter!). Vanuit het muntje-script kun je dus rechtstreeks bij body.score.
extends Area2D
func _on_body_entered(body: Node2D) -> void:
body.score += 1
print("Score: ", body.score)
queue_free()
| Code | Wat doet het? |
|---|---|
body | De node die het muntje raakt (jouw karakter) |
body.score | De score-variabele van die node |
body.score += 1 | Verhoog de score met 1 |
Stap 3: Test het
Start het spel met F5 en raap een paar muntjes op. Kijk in het Uitvoer-paneel onderaan — je zou daar moeten zien:
Score: 1
Score: 2
Score: 3
Predict: hoe krijg ik dit op het scherm?
Het werkt nu in de Uitvoer, maar je wil het op het scherm zien. Hoe zou je dat aanpakken?
Bekijk een (broze) poging
Je zou een Label kunnen toevoegen en in een Label-script proberen het karakter op te zoeken:
extends Label
func _process(delta: float) -> void:
text = "Score: " + str(get_node("../CharacterBody2D").score)
Maak je geen zorgen als
_processenstrnieuw zijn — die leer je rustig in les 18. De code hierboven is alleen om de pijn te laten zien.
Dit werkt — zolang je karakter precies CharacterBody2D heet en op de juiste plek in de scene-tree staat. Verschuif je het karakter, hernoem je het, of laad je een ander level? Crash.
In de volgende lessen zie je een schonere oplossing: globale variabelen + een Label die er netjes mee werkt.
Er gaat iets mis
Ik krijg Invalid get index 'score' (on base: 'Node2D')
Oorzaak: Het signal vangt ook andere bodies op die geen score-veld hebben — bijvoorbeeld een vijand of een ander object. body is in dat geval geen karakter.
Oplossing: Voor nu kun je aannemen dat alleen de speler je muntjes oppakt. Als je later vijanden toevoegt, controleer je eerst of body een speler is, bijvoorbeeld met een check op de naam of een group.
Mijn score begint elke keer weer bij 0 als ik het spel herstart
Oorzaak: Bij het opnieuw starten wordt het karakter opnieuw aangemaakt, en dus ook var score = 0. De score "leeft" zolang het karakter bestaat.
Oplossing: Dit lossen we in de volgende les op met global variables — variabelen die buiten één node leven en de hele speelsessie blijven bestaan.
Make-opdracht: voeg levens toe
Je hebt nu een score in je karakter. Pas dezelfde aanpak toe op een tweede variabele.
Opdracht: Voeg var levens = 3 toe aan je karakter. Laat een vijand bij contact body.levens -= 1 doen en de huidige waarde printen.
Tip
- Voeg
var levens = 3toe bovenaan je karakter-script, ondervar score = 0 - Open je vijand-script (uit de signals-les)
- Pas de
_on_body_entered-functie aan zodat hijbody.levens -= 1enprint("Levens: ", body.levens)doet - De vijand kan ook
queue_free()blijven aanroepen — of laat hem juist staan zodat hij blijft "pijn doen"
Antwoord
In je karakter-script:
extends CharacterBody2D
const SPEED = 300.0
const JUMP_VELOCITY = -800.0
var score = 0
var levens = 3
# ... rest van je script
In je vijand-script:
extends Area2D
func _on_body_entered(body: Node2D) -> void:
body.levens -= 1
print("Levens: ", body.levens)
queue_free()