Ga naar hoofdinhoud

Animaties in code

Je hebt nu drie animaties — idle, run en jump — maar ze spelen nog niet automatisch op het juiste moment. In deze les koppel je de animaties aan wat je karakter doet: op de grond rennen, in de lucht springen, of stilstaan.

Godot 4.7

Geschreven voor Godot 4.7.x — zie Godot-versies voor compatibiliteit.

Hier bouw je op verder: Booleans en vergelijken

Weet je dit niet meer zeker? Lees het terug voordat je verdergaat.

Voorspel: welke informatie heb je nodig?​

Welke vragen moet je script per frame beantwoorden om de juiste animatie te kiezen?

Antwoord

Drie vragen:

  1. Staat mijn karakter op de grond?
  2. Beweegt mijn karakter, en welke kant op?
  3. Staat mijn karakter stil?

Voor de eerste en de derde maak je een variabele. De tweede staat al in je script: velocity.x is positief als je naar rechts loopt en negatief als je naar links loopt.

Stap 1: Variabelen voor de toestand​

Plaats deze twee variabelen bovenaan je script (onder JUMP_VELOCITY, boven _physics_process):

var op_de_grond
var staat_stil

Dit is een var zónder =, en dat is nieuw. Zo'n regel maakt de variabele alvast aan, maar geeft hem nog geen waarde. Dat is hier precies de bedoeling: de echte waarde verandert elk frame, dus die vullen we straks pas in binnen _physics_process. Waar variabelen in je script horen te staan lees je terug in de GDScript-tips.

Hoe ziet je hele script er nu uit?
extends CharacterBody2D

const SPEED = 300.0 # gebruik jouw eigen waarde
const JUMP_VELOCITY = -800.0 # jouw waarde uit Opdracht 5.7.a

var op_de_grond
var staat_stil

func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta

if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY

var direction := Input.get_axis("ui_left", "ui_right")
if direction == 0:
velocity.x = move_toward(velocity.x, 0, SPEED)
else:
velocity.x = direction * SPEED

move_and_slide()

Nieuw stukje GDScript: het $-teken​

In deze les gebruik je voor het eerst regels als deze:

$AnimatedSprite2D.play('run')

Het $-teken pakt een child-node uit je Scene Tree, op naam. $AnimatedSprite2D betekent: zoek de child die AnimatedSprite2D heet, en daarvan roep je vervolgens .play('run') aan. Het is een korte schrijfwijze voor get_node("AnimatedSprite2D").

Let op: de naam achter $ moet précies overeenkomen met de naam in je Scene Tree, inclusief hoofdletters. Heb je jouw node Speler of Animaties genoemd, dan schrijf je dus $Animaties.play('run') — of je hernoemt de node terug naar AnimatedSprite2D, zodat je code gelijk blijft aan die van deze les.

Meer hierover staat in de GDScript-tips.

Stap 2: op_de_grond invullen en de jump-animatie​

Welke functie kun je gebruiken om te checken of je hoofdpersoon op de grond staat?

  • Geef op_de_grond de waarde van die functie.
  • Speel de jump-animatie af als de hoofdpersoon niet op de grond staat.
Bekijk het antwoord
op_de_grond = is_on_floor()
if not op_de_grond:
$AnimatedSprite2D.play('jump')

move_and_slide()

Voeg dit toe vóór move_and_slide() in je _physics_process, even ver ingesprongen als de regels erboven.

Opdracht 6.2.a: de idle-animatie als je stilstaat​

velocity.x houdt de horizontale snelheid bij. Vul de twee gaten in:

staat_stil = # vul aan: wanneer staat je karakter stil?
op_de_grond = is_on_floor()
if not op_de_grond:
$AnimatedSprite2D.play('jump')
elif staat_stil:
# vul aan: speel de idle-animatie af

move_and_slide()

Zo weet je dat het klopt: start met F5. Sta je stil op de grond, dan speelt idle. Loop je, dan niet.

Klik hier voor een tip.

Voor het eerste gat: welke waarde heeft velocity.x precies als er niemand op een toets drukt en je karakter is uitgeremd?

Voor het tweede gat: kijk naar de regel erboven, in de if. Dezelfde vorm, andere animatienaam.

Klik hier voor de oplossing.

velocity.x == 0 betekent stilstaan. Tot nu toe zag je == alleen bínnen een if, maar zo'n vergelijking is zelf ook een waarde: true of false. Die waarde kun je in een variabele bewaren:

velocity.xvelocity.x == 0staat_stil wordt
0truetrue
300falsefalse

Voeg de check toe boven je animatie-keten:

staat_stil = velocity.x == 0
op_de_grond = is_on_floor()
if not op_de_grond:
$AnimatedSprite2D.play('jump')
elif staat_stil:
$AnimatedSprite2D.play('idle')

move_and_slide()

Let op elif: de idle-animatie wordt alleen geprobeerd als jump níet aan is — anders zou je elke frame twee animaties tegelijk starten.

Opdracht 6.2.b: de run-animatie en spiegelen​

Nu de laatste twee takken van de keten. Met $AnimatedSprite2D.flip_h = true spiegel je het plaatje zodat je karakter naar links kijkt; met false kijkt hij weer naar rechts.

elif velocity.x > 0:
# vul aan: speel run af en laat hem naar rechts kijken
elif velocity.x < 0:
# vul aan: speel run af en laat hem naar links kijken

Zo weet je dat het klopt: loop naar rechts en je karakter rent naar rechts; loop naar links en hij rent gespiegeld terug.

Klik hier voor een tip.

Elke tak heeft twee regels nodig: één om de animatie te starten en één om flip_h goed te zetten. Bedenk bij welke richting velocity.x negatief is.

Klik hier voor de oplossing.
extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -800.0 # jouw waarde uit Opdracht 5.7.a

var op_de_grond
var staat_stil

func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta

if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY

var direction := Input.get_axis("ui_left", "ui_right")
if direction == 0:
velocity.x = move_toward(velocity.x, 0, SPEED)
else:
velocity.x = direction * SPEED

staat_stil = velocity.x == 0
op_de_grond = is_on_floor()
if not op_de_grond:
$AnimatedSprite2D.play('jump')
elif staat_stil:
$AnimatedSprite2D.play('idle')
elif velocity.x > 0:
$AnimatedSprite2D.play('run')
$AnimatedSprite2D.flip_h = false
elif velocity.x < 0:
$AnimatedSprite2D.play('run')
$AnimatedSprite2D.flip_h = true

move_and_slide()

Er gaat iets mis​

Mijn karakter speelt altijd de jump-animatie, ook op de grond

Oorzaak: De variabele op_de_grond wordt niet (op tijd) bijgewerkt. Daardoor blijft not op_de_grond waar.

Oplossing: Zorg dat op_de_grond = is_on_floor() boven je if/elif-keten staat — niet eronder en niet binnen een if-blok.

Mijn karakter kijkt de verkeerde kant op tijdens het rennen

Oorzaak: flip_h staat op de verkeerde waarde.

Oplossing: Onthoud:

  • flip_h = false → karakter kijkt rechts (standaard).
  • flip_h = true → karakter kijkt links (gespiegeld).

Dus bij velocity.x < 0 (links bewegen): flip_h = true.

De idle-animatie start niet als ik stilsta

Oorzaak: Twee mogelijke oorzaken:

  1. De volgorde van je if / elif is verkeerd: velocity.x > 0 of < 0 wordt eerder waar dan staat_stil.
  2. staat_stil wordt bijgewerkt vóórdat move_toward de snelheid op 0 heeft gezet, en houdt dan een frame lang de oude waarde vast.

Over dat tweede: met stap SPEED (zoals in Deel 6 — Stoppen) maakt move_toward de snelheid in één frame exact 0. Alleen als je bewust een kleinere stap koos voor een glij-effect, blijft velocity.x nog een paar frames ongelijk aan nul en start idle iets later — dat is dan geen bug, maar het gevolg van het glijden.

Oplossing:

  • Controleer dat elif staat_stil: staat tussen if not op_de_grond: en elif velocity.x > 0:.
  • Werk staat_stil bij vlak voor je if-keten, dus ná de regel met move_toward.

Staat je fout er niet bij? In Fouten zoeken staat hoe je hem zelf opspoort.