Skip to main content

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()
CodeWat doet het?
bodyDe node die het muntje raakt (jouw karakter)
body.scoreDe score-variabele van die node
body.score += 1Verhoog 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 _process en str nieuw 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 = 3 toe bovenaan je karakter-script, onder var score = 0
  • Open je vijand-script (uit de signals-les)
  • Pas de _on_body_entered-functie aan zodat hij body.levens -= 1 en print("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()