Ga naar hoofdinhoud

Het bewegingsscript bouwen — Deel 7: Springen

Je karakter loopt en valt. Er ontbreekt één ding: omhoog. In deze les maak je het bewegingsscript af.

Godot 4.7

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

Hier bouw je op verder: And, or en elif

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

Wat je nu gaat toevoegen​

Twee begrippen: het verschil tussen just_pressed en pressed, en and om twee voorwaarden te combineren. Daarna is je bewegingsscript compleet en heb je het helemaal zelf getypt.

Voorspel: waarom is springen negatief?​

Springen betekent velocity.y een waarde geven. Moet dat een positief of een negatief getal zijn?

Antwoord

Negatief. In Godot ligt (0, 0) in de linkerbovenhoek van het scherm:

  • naar rechts wordt x groter
  • naar beneden wordt y groter
  • naar boven wordt y dus kleiner, en dat betekent negatief

Een sprong is beweging naar boven, dus velocity.y moet negatief worden.

Godot coördinatenstelsel

Stap 1: De sprongkracht als constante​

Zet deze regel onder je bestaande const SPEED:

const JUMP_VELOCITY = -400.0

Een negatief getal, precies zoals je voorspelde. Hoe verder van nul, hoe hoger de sprong.

Stap 2: De sprong zelf​

Zet dit binnen de functie, ónder het zwaartekracht-blok en bóven de regels voor lopen:

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

ui_accept is een standaardactie van Godot, gekoppeld aan de spatiebalk en Enter.

Stap 3: just_pressed of pressed?​

Godot heeft twee manieren om naar een toets te kijken:

FunctieWanneer is het true?
Input.is_action_pressed("ui_accept")zolang je de toets ingedrukt houdt
Input.is_action_just_pressed("ui_accept")alleen op het ene frame dat je hem indrukt

Wat denk je dat er gebeurt als je just_pressed vervangt door pressed?

Antwoord

Zolang je de spatie vasthoudt, blijft je karakter springen: hij landt en is meteen weer weg, als een stuiterbal. Hoger dan een gewone sprong komt hij niet, want and is_on_floor() laat de sprong alleen toe op de grond. Maar elke keer dat hij landt, is de toets nog ingedrukt.

Met just_pressed gebeurt het één keer per druk, en moet de speler loslaten voor een volgende sprong.

Het verschil staat ook in de GDScript-tips.

Stap 4: Twee voorwaarden met and​

De check bestaat uit twee delen: de speler drukt op de knop en het karakter staat op de grond. Met and moeten ze allebei waar zijn.

Wat gebeurt er zonder dat tweede deel?

Antwoord

Je kunt in de lucht springen. Tijdens een sprong nog eens drukken geeft opnieuw de volle sprongkracht, en zo kun je jezelf omhoog blijven pompen. Elk gat is dan over te steken en je level wordt betekenisloos.

Stap 5: = en niet +=​

Bij de zwaartekracht gebruikte je +=, hier gebruik je =. Dat is bewust.

Maakt het in jouw script uit als je hier velocity.y += JUMP_VELOCITY schrijft?

Antwoord

Nu nog niet. Je springt alleen als je op de grond staat, en daar is velocity.y 0: het zwaartekracht-blok telt dan niets op. 0 + (-400) blijft -400.

Het gaat mis zodra je ook in de lucht mag springen, zoals bij dubbel springen in opdracht 5.7.b. Val je al met velocity.y = 200, dan geeft += 200 + (-400) = -200, en springt je karakter half zo hoog. Met = vervang je de verticale snelheid helemaal door -400. Een sprong is dan altijd even hoog, waar je ook bent.

Stap 6: Test het​

Start met F5. Je karakter loopt, springt met de spatiebalk, valt terug en kan niet in de lucht nog een keer springen.

Je bewegingsscript is compleet — en je hebt geen regel gekregen die je niet zelf hebt getypt.

Hoe anderen dit doen​

Zoek je straks zelf een tutorial op, dan zie je vaak een andere route: veel makers laten Godot het bewegingsscript invullen met de kant-en-klare template, en passen daarna wat getallen aan. Sneller, maar je slaat het begrijpen over.

Nu je je eigen versie hebt, kun je zo'n video met winst bekijken: je herkent elke regel en je ziet meteen waar iemand iets anders doet dan jij.

Je complete script​

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

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()
Klik om WASD-besturing toe te voegen (W = springen, A = links, D = rechts)

Veel platformers laten je naast de pijltjestoetsen ook met WASD spelen. Dat doe je door extra toetsen te koppelen aan bestaande acties, zonder de pijltjestoetsen te slopen.

Stap 1 — Open de Input Map

  1. Klik bovenin op Project → Project Settings.
  2. Klik op het tabblad Input Map (naast General).
  3. In de lijst onder All Actions staan ui_accept, ui_left, ui_right en meer. Klap een actie open met het pijltje ervoor om de huidige toetsen te zien.

Stap 2 — Voeg W toe aan ui_accept

  1. Zoek ui_accept en klik op het plus-icoontje (+) ernaast.
  2. Er verschijnt een venster: druk op de W-toets.
  3. Klik op OK.

Stap 3 — Doe hetzelfde voor A en D

Bij ui_left: klik +, druk A, klik OK. Bij ui_right: klik +, druk D, klik OK.

Stap 4 — Test

Start met F5. WASD en de pijltjestoetsen werken nu allebei.

tip

Een toets juist vervangen in plaats van toevoegen? Klap de actie open en klik op het prullenbak-icoontje naast de toets die weg mag.

Opdracht 5.7.a: kies je sprongkracht​

In Opdracht 5.5.a koos je een loopsnelheid. Stem je sprong daar nu op af. Probeer minstens drie waarden voor JUMP_VELOCITY, bijvoorbeeld -400.0, -800.0 en -1200.0, en kies de waarde waarmee je net op je hoogste platform komt.

Klik hier voor een tip.

Hoe negatiever het getal, hoe harder je omhoog gaat. Spring vanaf de vloer naast een platform en kijk of je er bovenop komt, en of je bij een gat niet over het volgende platform heen schiet.

Klik hier voor de oplossing.

Een goede waarde hangt af van je level. Als richtlijn, met de zwaartekracht van Godot:

JUMP_VELOCITYZo hoog kom je ongeveer
-400.085 pixels
-800.0330 pixels
-1200.0740 pixels

Twee keer zo hard afzetten geeft dus vier keer zo hoog. Vanaf hoofdstuk 6 staat in de lessen -800.0. Koos jij iets anders, houd dan je eigen waarde aan.

Opdracht 5.7.b: voeg een eigen kracht toe​

Je script kent nu vallen, lopen en springen. Voeg er zelf iets bij dat niet in de les staat. Kies er één:

  • Sprinten: houd shift ingedrukt en je loopt sneller.
  • Dubbel springen: één keer extra springen terwijl je in de lucht bent.
info

Dit is de eerste opdracht zonder uitgewerkte oplossing, en dat is met opzet. Tot nu toe kon je je antwoord vergelijken met het onze. Vanaf hier gaat het erom dat je zelf iets bedenkt met wat je kent — een oplossing die je overschrijft leert je iets anders dan een oplossing die je vindt.

Denk na​

Beantwoord deze vragen voor jezelf voordat je gaat typen. Ze wijzen allebei de weg.

Bij sprinten:

  • Welke waarde moet er anders zijn als shift ingedrukt is? En welke regel zet die waarde nu?
  • Je hebt een actie nodig die "shift" heet. Waar maak je die aan? (Zie het WASD-blok hierboven.)

Bij dubbel springen:

  • Je moet onthouden hóé vaak er al gesprongen is sinds de laatste landing. Een const kan dat niet bijhouden — wat wel?
  • Waar in je functie weet je zeker dat het karakter net geland is?
Vastgelopen?

Bouw het in twee helften. Zorg eerst dat je in Uitvoer kunt zien dat je nieuwe toets wordt herkend, met een print(). Werkt dat, dan pas de snelheid of de sprong aanpassen.

Zo weet je bij een fout meteen aan welke kant je moet zoeken: bij het uitlezen van de toets, of bij het toepassen ervan.

Er gaat iets mis​

Mijn karakter springt niet

Oorzaak: De if staat op het verkeerde niveau, of ui_accept is niet aan een toets gekoppeld.

Oplossing:

  1. Controleer dat de if-regel op hetzelfde niveau staat als de andere regels binnen de functie.
  2. Controleer in Project → Project Settings → Input Map dat ui_accept bestaat en aan de spatiebalk hangt.
  3. Zet print("spring") binnen de if om te zien of hij überhaupt wordt bereikt.
Mijn karakter blijft stuiteren zolang ik de spatie vasthoud

Oorzaak: Er staat is_action_pressed in plaats van is_action_just_pressed. Elke keer dat je karakter landt, is de toets nog ingedrukt, dus springt hij meteen weer.

Oplossing: Vergelijk je regel letterlijk met die uit Stap 2. Zie Stap 3 voor het verschil.

Mijn karakter kan in de lucht steeds opnieuw springen

Oorzaak: De and is_on_floor() ontbreekt. Dan geeft elke druk op de spatie de volle sprongkracht, ook midden in een sprong.

Oplossing: Zet and is_on_floor() achter de check op de toets, zoals in Stap 2.


← Deel 6 — Stoppen · Volgende: Fouten zoeken →