Subsecties van Python sessies
Sessie 1: Catch the Stars
In deze sessie bouw je een mini-spel: een ster valt naar beneden en jij vangt hem op met een basket. Aan het einde van de sessie beweegt alles, houdt het spel bij hoeveel sterren je vangt, en heb je je eerste eigen game.
Wat je vandaag leert
- Variabelen gebruiken om objecten te positioneren
- De
draw() functie: wat je elke frame tekent - De
update() functie: wat er elke frame verandert - Toetsenbord-input: bewegen met pijltjestoetsen
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py in Thonny. - Klik op de groene Run-knop. Je ziet een donkerblauw venster met een basket onderaan en een ster bovenaan, maar niks beweegt nog.
- Problemen? Kijk bij Thonny instellen.
Stap 1: Laat de ster vallen
De update() functie draait 60 keer per seconde. Alles wat je daarin zet, wordt dus 60 keer per seconde uitgevoerd. Dat is hoe beweging werkt in een game.
Op dit moment staat er alleen pass in update(). Dat betekent “doe niks”. Verwijder pass en voeg dit toe:
def update():
star.y = star.y + 3
Klik op Run. De ster valt nu van boven naar beneden. Als hij het scherm uit valt, verdwijnt hij. Dat lossen we zo op.
Wat gebeurt hier? star.y is de verticale positie van de ster. Hoe groter y, hoe lager op het scherm. Door elke frame + 3 toe te voegen, zakt de ster steeds een beetje.
Het coördinatenstelsel: (0, 0) zit linksboven, niet linksonder zoals in wiskunde. x loopt naar rechts, y loopt naar beneden. De ster begint op y = 30 (bijna helemaal boven), de basket staat op y = 370 (bijna helemaal onder).

Beweeg je muis over het scherm hieronder om de coördinaten te zien:
Beweeg je muis over het scherm om de coördinaten te zien.
Wil je meer weten over hoe het scherm werkt? → Coördinaten uitgelegd
Pas de schuifbalken aan en kijk hoe actor.x en actor.y veranderen als de actor beweegt:
Stap 2: ✅ Basic: laat de basket bewegen
Tijd om de basket te besturen. Pygame Zero heeft een handige keyboard-variabele die bijhoudt welke toetsen ingedrukt zijn.
Voeg dit toe aan update(), na de regel over de ster:
def update():
star.y = star.y + 3
if keyboard.left:
basket.x = basket.x - 5
if keyboard.right:
basket.x = basket.x + 5
Klik op Run en gebruik de pijltjestoetsen. De basket beweegt nu mee!
Tip (optioneel, telt als Stretch): Als je de basket te ver naar links of rechts beweegt, verdwijnt hij van het scherm. Kun jij een check toevoegen die dat voorkomt? Hint: gebruik WIDTH en vergelijk met basket.x.
Stap 3: ⭐ Stretch: vang de ster
Nu wil je dat er iets gebeurt als de basket de ster raakt. Daarvoor gebruik je colliderect. Die controleert of twee rechthoeken elkaar overlappen.
Voeg dit toe aan update():
if star.colliderect(basket):
star.y = 0
De ster springt terug naar boven als je hem vangt. Maar wat als je hem mist? Voeg ook dit toe:
if star.y > HEIGHT:
star.y = 0
Bonus: Laat de ster elke keer op een willekeurige plek terug verschijnen. Voeg bovenaan het bestand toe:
Vervang dan star.y = 0 (op beide plekken) door:
star.x = random.randint(20, WIDTH - 20)
star.y = 0
Nu valt de ster steeds op een andere plek. Veel moeilijker te vangen!
Stap 4: 🔥 Expert: voeg een score toe
Een echte game houdt bij wat je scoort. Daarvoor heb je een variabele nodig die buiten de functies leeft: een globale variabele.

Klik op de knop hieronder om te zien hoe score verandert elke keer dat je een ster vangt:
Voeg dit toe bovenaan, buiten alle functies (na de regels over basket en star):
In draw(), voeg toe:
screen.draw.text(f"Score: {score}", topleft=(10, 10), color="white")
In update(), pas de catch-code aan zodat de score omhoog gaat:
if star.colliderect(basket):
global score
score = score + 1
star.x = random.randint(20, WIDTH - 20)
star.y = 0
global score vertelt Python: “ik bedoel de score van buiten deze functie, niet een nieuwe lokale variabele.” Zonder die regel krijg je een foutmelding.
Klik op Run. De score staat linksboven en telt op elke keer dat je een ster vangt!
Showcase
Laat je spel zien aan een coach en een buddy. Vertel wat je gemaakt hebt: wat werkt, en wat je nog extra hebt toegevoegd.
Tot de volgende keer!
“Volgende keer: dingen die TERUGSLAAN. En ze gaan BOEM, met echt geluid.”
Neem mee naar huis
Probeer thuis één van deze uitbreidingen. Bij elke staat een code-hint om je op weg te helpen.
Beperk levens — Voeg levens = 3 toe. Bij een misser (star.y > HEIGHT): levens -= 1. Stop het spel als levens == 0 met game_over = True en toon “Game Over” in draw().
Willekeurige ster-kleur — Bij elke vangst: geef de ster een nieuwe kleur met random.randint(50, 255) voor rood, groen en blauw. Begin bij 50, niet bij 0 — anders is de ster soms zwart en onzichtbaar.
Achtergrond — Teken vaste sterren op de achtergrond in draw() voor de score. Gebruik screen.draw.filled_circle(x, y, 2, "white") op 20 willekeurige posities. Zaai random.seed(42) zodat ze niet flikkeren.
Tweede ster — Maak sterren = [star, Actor("star")]. Geef elke ster een eigen x. Werk ze allebei bij in update() en teken ze in draw().
Hoge score — Houd high_score bij. Als score > high_score: high_score = score. Toon f"Beste: {high_score}" naast de score.
Basket kleiner — Na elke 5 punten: basket.width = max(30, basket.width - 5). Zet basket.width terug bij herstart.
Bom — Voeg een rode cirkel toe die af en toe valt. Gebruik een timer bom_timer en random.randint om te bepalen wanneer hij verschijnt. Als de basket de bom raakt: score -= 2.
Moeilijkheidsgraad — Na elke 5 sterren: verhoog de valsnelheid met 1. Bouw een maximum in: max(3, star_snelheid).
Vastgelopen? Vraag het volgende dojo aan een coach, of probeer gewoon iets anders. Programmeren is doen.
Bekijk de cheatsheet voor deze sessie
Sessie 2: Dodge Meteors
Je ruimteschip zweeft in de donkere ruimte terwijl meteoren van boven naar beneden komen. Ontwijk ze, of verlies een leven. Hoe langer je overleeft, hoe sneller ze gaan. En deze keer bouw je ook Dojo Defender: het grotere project dat elke sessie groeit.
Wat je vandaag leert
- Lijsten gebruiken om meerdere objecten bij te houden
- Objecten spawnen (aanmaken) en verwijderen
- Levens bijhouden en een game-over scherm tonen
- Dojo Defender: je eigen ruimteschip toevoegen aan het grotere project
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py. - Klik op Run. Je ziet je ruimteschip onderaan, maar er vallen nog geen meteoren.
- Problemen? Kijk bij Thonny instellen.
Stap 1: Laat meteoren spawnen
Vul de functie spawn_meteor() in. Een meteoor is een Actor die bovenaan het scherm begint op een willekeurige x-positie:
import random
def spawn_meteor():
rock = Actor('meteor')
rock.x = random.randint(30, WIDTH - 30)
rock.y = 0
meteors.append(rock)
Roep de functie aan in update(), maar niet élke frame, anders wordt het scherm meteen volgestort. De update() functie draait 60 keer per seconde. Gebruik dat om een teller bij te houden:
Zie hieronder hoe snel een meteoor beweegt bij verschillende snelheden en hoeveel pixels dat per seconde is:
Gebruik een teller:
# bovenaan, buiten de functies:
timer = 0
def update():
global timer
timer += 1
if timer % 60 == 0: # elke seconde (60 frames)
spawn_meteor()
Klik op Run. Na een seconde verschijnt de eerste meteoor, maar hij beweegt nog niet.
Stap 2: ✅ Basic: meteoren laten vallen en verdwijnen
Laat alle meteoren in de lijst zakken, en verwijder ze als ze het scherm uit vallen:
def update():
global timer
timer += 1
if timer % 60 == 0:
spawn_meteor()
for rock in meteors[:]: # [:] = kopie zodat je veilig kunt verwijderen
rock.y += 4
if rock.y > HEIGHT + 30:
meteors.remove(rock)
Collision detecteren: Als een meteoor het schip raakt, verlies je een leven. Voeg dit toe in de loop:
if rock.colliderect(ship):
meteors.remove(rock)
global lives
lives -= 1
if lives <= 0:
# TODO: game over (stap 3)
pass
Stap 3: ⭐ Stretch: game over en snelheid opvoeren
Game over: Voeg een variabele game_over = False toe bovenaan. Als lives == 0, zet game_over = True. In draw(), toon een tekst als game_over True is:
if game_over:
screen.draw.text(
"GAME OVER",
center=(WIDTH / 2, HEIGHT / 2),
color="red",
fontsize=60,
)
Stop het bewegen in update() als game_over True is:
def update():
if game_over:
return
...
Snelheid verhogen: Laat meteoren sneller gaan naarmate de score stijgt:
snelheid = 3 + score // 5 # elke 5 punten +1 snelheid
rock.y += snelheid
Stap 4: 🔥 Expert: score en meerdere meteoorgroottes
Score: Elke seconde dat je overleeft, +1 punt. Voeg global score toe en verhoog in update():
if timer % 60 == 0:
global score
score += 1
spawn_meteor()
Meerdere groottes: Maak kleine, middel en grote meteoren. Gebruik een schaal-variabele en pas de hitbox aan:
def spawn_meteor():
rock = Actor('meteor')
rock.x = random.randint(30, WIDTH - 30)
rock.y = 0
rock.schaal = random.choice([0.5, 1.0, 1.5])
meteors.append(rock)
Kleinere meteoren bewegen sneller; grotere zijn moeilijker te ontwijken maar geven meer punten.
Dojo Defender
Download de Dojo Defender starter voor vandaag.
Dit is de basis van het project dat elke sessie groeit. Voeg vandaag je ruimteschip toe en laat het bewegen met de pijltjestoetsen.
Was je er vorige keer niet bij? Geen probleem — download de oplossing van vorige keer en je kan meteen mee.
Het volledige Dojo Defender werkblad vind je op de Dojo Defender pagina.
Showcase
Laat je spel zien aan een coach en een buddy. Hoe lang overleef jij? Wie haalt de hoogste score?
Tot de volgende keer!
“Volgende keer: je eigen ruimteschip SCHIET TERUG. Vijanden in formatie, en jij blast ze weg.”
Neem mee naar huis
- Makkelijk: verander de achtergrondkleur naar dieppaars of donkergroen.
- Middel: voeg een geluid toe als een meteoor het schip raakt (
sounds/hit.wav). - Lastig: maak meteoren sneller naarmate er meer op het scherm zijn (niet alleen de score).
- Erg lastig: voeg power-ups toe: een gouden ster die je een extra leven geeft als je hem aanraakt.
Bekijk de cheatsheet voor deze sessie
Sessie 3: Space Blaster
Vijanden staan in formatie bovenaan het scherm. Jij staat onderaan met een ruimteschip en één doel: ze allemaal uitschakelen voordat ze de bodem bereiken. Druk op SPATIE om te schieten, en mis niet.
Wat je vandaag leert
- Kogels bijhouden in een lijst
- Een kogel aanmaken als je op SPATIE drukt
- Collision tussen kogels en vijanden
- Game over als een vijand de bodem raakt
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py. - Klik op Run. Je ziet het schip onderaan en 12 vijanden in een raster, maar niks beweegt en je kunt nog niet schieten.
Stap 1: Laat het schip bewegen
Het schip beweegt al met de pijltjestoetsen. Controleer de code in update(). Zorg dat het schip niet buiten het scherm gaat:
if keyboard.left and ship.x > 30:
ship.x -= 5
if keyboard.right and ship.x < WIDTH - 30:
ship.x += 5
Stap 2: ✅ Basic: schieten met SPATIE
Vul de functie shoot() in. Een kogel is een Actor die begint op de positie van het schip:
def shoot():
kogel = Actor('bullet')
kogel.x = ship.x
kogel.y = ship.y - 20
bullets.append(kogel)
Roep shoot() aan als de spatiebalk wordt ingedrukt. Gebruik on_key_down (Pgzero-stijl):
def on_key_down(key):
if key == keys.SPACE:
shoot()
Laat de kogels omhoog bewegen in update() en verwijder ze als ze het scherm uit gaan:
for kogel in bullets[:]:
kogel.y -= 8
if kogel.y < -10:
bullets.remove(kogel)
Stap 3: ⭐ Stretch: vijanden raken
colliderect controleert of de rechthoekige hitbox van twee actors overlapt. Beweeg je muis over het scherm hieronder om te zien wanneer dat gebeurt:
Controleer in update() of een kogel een vijand raakt:
for kogel in bullets[:]:
kogel.y -= 8
if kogel.y < -10:
bullets.remove(kogel)
continue
for vijand in enemies[:]:
if kogel.colliderect(vijand):
bullets.remove(kogel)
enemies.remove(vijand)
global score
score += 10
break
Win-conditie: Als enemies leeg is, heb je gewonnen:
if not enemies:
screen.draw.text("JE WINT!", center=(WIDTH/2, HEIGHT/2), color="yellow", fontsize=60)
Stap 4: 🔥 Expert: vijanden bewegen en game over
Laat de vijanden langzaam naar beneden komen. Gebruik een timer:
vijand_timer = 0
def update():
global vijand_timer
vijand_timer += 1
if vijand_timer % 90 == 0: # elke 1,5 seconde
for vijand in enemies:
vijand.y += 20
Game over als een vijand de bodem bereikt:
for vijand in enemies:
if vijand.y > HEIGHT - 30:
global game_over
game_over = True
Snellere schietfrequentie: Bouw een cooldown in zodat de ninja niet oneindig snel kan schieten:
shoot_cooldown = 0
def update():
global shoot_cooldown
if shoot_cooldown > 0:
shoot_cooldown -= 1
def on_key_down(key):
global shoot_cooldown
if key == keys.SPACE and shoot_cooldown == 0:
shoot()
shoot_cooldown = 15
Showcase
Laat je spel zien aan een coach. Hoe snel maak jij alle vijanden weg? Vergelijk scores met een buddy.
Tot de volgende keer!
“Volgende keer: twee spelers, één bal: PONG. En je leert echte pygame zonder pgzrun.”
Neem mee naar huis
- Makkelijk: verander de kleur van de kogels of de vijanden.
- Middel: laat vijanden links en rechts bewegen (één richting per stap, keer om aan de rand).
- Lastig: voeg een second wave toe: als alle vijanden weg zijn, spawn een nieuwe rij die sneller daalt.
- Erg lastig: laat vijanden ook terugschieten: willekeurig een kogel omlaag sturen elke N frames.
Bekijk de cheatsheet voor deze sessie
Dojo Defender
Download de Dojo Defender starter voor vandaag.
Was je er vorige keer niet bij? Download de oplossing van sessie 1 en begin daarmee.
Het volledige werkblad: Dojo Defender Sessie 2.
Sessie 4: Pong
Twee paddles, één bal: het klassieke Pong-spel. Maar er is een verrassing: deze sessie schrijf je het spel in echte pygame, zonder pgzrun. Je leert de game loop zelf Installeren. Dat is hoe de meeste echte games werken.
Wat je vandaag leert
- De pygame game loop: events, update, draw
pygame.Rect voor rechthoeken en botsingen- Bal laten stuiteren (snelheid omkeren)
- Score bijhouden voor twee spelers
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py. - Klik op Run. Je ziet twee paddles en een gele bal in het midden, maar de bal beweegt nog niet.
Verschil met pgzrun: Er zijn geen draw() en update() functies meer. Alles zit in één while running: loop.
Stap 1: Laat de bal bewegen
Zoek de regels:
# bal.x += ball_dx # zet dit aan als je klaar bent
# ball.y += ball_dy
Verwijder de # voor beide regels. Maar stel eerst een startsnelheid in. Zoek ball_dx, ball_dy = 0, 0 en verander naar:
Klik op Run. De bal beweegt nu, maar verdwijnt door de rand. Dat lossen we op in stap 2.
Stap 2: ✅ Basic: bal stuitert op muren en paddles
Voeg na ball.x += ball_dx en ball.y += ball_dy het volgende toe:
# Stuiteren op boven- en onderrand
if ball.top <= 0 or ball.bottom >= HEIGHT:
ball_dy = -ball_dy
# Stuiteren op paddles
if ball.colliderect(left_paddle) or ball.colliderect(right_paddle):
ball_dx = -ball_dx
De bal stuitert nu oneindig. Voeg ook grenzen toe voor de paddles zodat ze niet buiten het scherm gaan. Kijk naar de code die al in de starter staat.
Stap 3: ⭐ Stretch: score bijhouden
Als de bal links het scherm uitvalt, scoort de rechter speler. Als hij rechts uitvalt, scoort de linker:
# Bal uit links → rechts scoort
if ball.left <= 0:
score_right += 1
ball.center = (WIDTH // 2, HEIGHT // 2)
ball_dx = 4
# Bal uit rechts → links scoort
if ball.right >= WIDTH:
score_left += 1
ball.center = (WIDTH // 2, HEIGHT // 2)
ball_dx = -4
De score staat al in draw(). Controleer dat de variabelen kloppen.
Stap 4: 🔥 Expert: win-conditie en snelheid verhogen
Win bij 5 punten: Voeg een variabele won toe. Als een speler 5 bereikt, stop dan het spel:
if score_left >= 5:
won = "Links wint!"
if score_right >= 5:
won = "Rechts wint!"
Toon de winnaar op het scherm en stop de beweging.
Snelheid verhogen: Na elke rally wordt de bal een beetje sneller:
if ball.colliderect(left_paddle) or ball.colliderect(right_paddle):
ball_dx = -ball_dx * 1.05 # 5% sneller
ball_dy = ball_dy * 1.05
Bouw een maximum in: ball_dx = max(-12, min(12, ball_dx)).
Showcase
Speel een potje tegen een buddy. Eerste naar 5 punten wint. Laat het zien aan een coach.
Tot de volgende keer!
“Volgende keer: Breakout: de bal beukt stenen kapot. En er is GELUID.”
Neem mee naar huis
- Makkelijk: verander de kleur van de bal of de paddles.
- Middel: maak één paddle groter naarmate die speler verliest (handicap).
- Lastig: voeg een AI-tegenstander toe: de rechter paddle volgt automatisch de bal.
- Erg lastig: voeg power-ups toe: een item dat de bal verdubbelt of de paddle groter maakt.
Dojo Defender
Vandaag verhuist Dojo Defender naar echte Pygame!
Download de starter.
Was je er niet bij? Download de oplossing van sessie 2.
Werkblad: Dojo Defender Sessie 3.
Bekijk de cheatsheet voor deze sessie
Sessie 5: Breakout
Een bal kaatst heen en weer en beukt rijen gekleurde stenen kapot. Jij bestuurt de paddle om de bal in de lucht te houden. En deze keer hoor je het ook: er zijn geluidseffecten bij elke botsing.
Wat je vandaag leert
- Geluid laden en afspelen met
pygame.mixer - Botsingen met meerdere objecten (lijst van stenen)
- De bal laten stuiteren in de juiste richting
- Win- en verlies-scherm bouwen
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py. - Klik op Run. Je ziet de paddle, de bal en de stenen. De bal beweegt al horizontaal maar niet verticaal. Dat ga jij aanpassen.
Stap 1: Laat de bal verticaal bewegen
Zoek deze regel in de starter:
ball_dx, ball_dy = 4, 0
# ball_dy = -4 ← verwijder de # om de bal te laten bewegen!
Verwijder de # voor ball_dy = -4. Nu heeft de bal een verticale snelheid. Voeg beweging toe in de game loop (zoek de update-sectie):
ball.x += ball_dx
ball.y += ball_dy
Klik op Run. De bal beweegt diagonaal maar verdwijnt door de randen.
Stap 2: ✅ Basic: bal stuitert op muren en paddle
Voeg stuiteren toe:
# Boven-, links- en rechtsrand
if ball.left <= 0 or ball.right >= WIDTH:
ball_dx = -ball_dx
if ball.top <= 0:
ball_dy = -ball_dy
# Paddle
if ball.colliderect(paddle):
ball_dy = -ball_dy
if snd_hit:
snd_hit.play()
Levens: Als de bal de onderkant bereikt, verlies je een leven:
if ball.top > HEIGHT:
levens -= 1
# Reset bal bovenop de paddle
ball.center = (paddle.centerx, paddle.top - BALL_SIZE)
ball_dy = -4
Stap 3: ⭐ Stretch: stenen breken
Controleer collision met elke steen in de loop:
for steen in stenen[:]:
if ball.colliderect(steen['rect']):
stenen.remove(steen)
ball_dy = -ball_dy
score += 10
if snd_hit:
snd_hit.play()
break # slechts één steen per frame breken
Win-conditie: Als alle stenen weg zijn, heeft de ninja gewonnen. Toon een bericht:
if not stenen:
# toon win-scherm
Stap 4: 🔥 Expert: levens, explosiegeluid en snelheid
Explosiegeluid als een steen breekt (gebruik snd_explode uit de starter):
if snd_explode:
snd_explode.play()
Game over bij 0 levens: toon een scherm en stop de bal.
Snelheid verhogen naarmate er minder stenen overblijven:
snelheid_factor = 1 + (1 - len(stenen) / totaal_stenen) * 0.5
ball_dx_huidig = ball_dx * snelheid_factor
Nieuwe rij stenen als alles weg is: roep stenen = maak_stenen() opnieuw aan en verhoog de moeilijkheidsgraad.
Showcase
Wie haalt de meeste stenen weg? Vergelijk scores en laat je coach de hoogste streak zien.
Tot de volgende keer!
“Volgende keer: zwaartekracht. Jouw karakter valt, en jij moet hem laten springen op platforms.”
Neem mee naar huis
- Makkelijk: verander de kleuren van de stenen naar jouw favoriete kleuren.
- Middel: maak sommige stenen twee keer zo sterk (ze moeten tweemaal geraakt worden).
- Lastig: voeg een power-up toe die de paddle tijdelijk breder maakt.
- Erg lastig: voeg een tweede bal toe die spawnt als score > 50.
Bekijk de cheatsheet voor deze sessie
Dojo Defender
Dojo Defender krijgt een menu en nieuwe vijandtypes!
Download de starter.
Was je er niet bij? Download de oplossing van sessie 3.
Werkblad: Dojo Defender Sessie 4.
In deze sessie bouw je een micro-platformer. Je speler heeft zwaartekracht, kan springen, en verzamelt sterren op platforms. Je gebruikt voor het eerst pygame direct, zonder pgzrun, en voegt geluidseffecten toe met pygame.mixer.
Wat je vandaag leert
- Zwaartekracht simuleren met een
vel_y variabele - Springen door
vel_y negatief te maken - Platformbotsingen detecteren met
pygame.Rect - Items verzamelen (collision met sterren)
- Geluiden afspelen met
pygame.mixer
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py in Thonny. - Klik op de groene Run-knop. Je ziet een venster met een speler, platforms en sterren, maar de speler valt nog niet.
- Problemen? Vraag een coach.
Stap 1: Zwaartekracht
In een platformer valt de speler continu naar beneden, tenzij hij op een platform staat. We simuleren dat met vel_y: een verticale snelheid die elke frame groter wordt door zwaartekracht.
Zoek de # STAP 1 comment in main.py en vervang de pass door:
# Zwaartekracht toepassen
vel_y += GRAVITY
player_rect.y += vel_y
# Controleer of speler op een platform staat
on_ground = False
for platform in platforms:
if (player_rect.colliderect(platform) and vel_y > 0):
player_rect.bottom = platform.top
vel_y = 0
on_ground = True
GRAVITY = 0.5 staat al bovenaan het bestand. Klik Run. De speler valt nu naar het dichtstbijzijnde platform en blijft daar staan.
Wat gebeurt hier? Elke frame wordt vel_y iets groter (de speler versnelt naar beneden). Als de speler een platform raakt terwijl hij naar beneden valt (vel_y > 0), zet je zijn onderkant (bottom) precies op de bovenkant van het platform en stop je de val (vel_y = 0).
Stap 2: ✅ Basic: springen
Een platformer zonder springen is maar half af. Druk op SPATIE om te springen: dat is niets anders dan vel_y plotseling negatief maken.
Zoek de # STAP 2 comment en voeg toe:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_rect.x -= SPEED
if keys[pygame.K_RIGHT]:
player_rect.x += SPEED
# Springen — alleen als je op de grond staat
if keys[pygame.K_SPACE] and on_ground:
vel_y = -12
Klik Run en test:
- Pijltjestoetsen: beweeg links/rechts
- SPATIE: spring omhoog
Tip: Als de speling te hoog of te laag voelt, verander dan -12 in -10 (lager springen) of -15 (hoger springen).
Stap 3: ⭐ Stretch: sterren verzamelen
Laten we iets te verzamelen toevoegen. De starter heeft al een lijst stars met pygame.Rect-objecten. Jij schrijft de botsingsdetectie.
Zoek de # STAP 3 comment:
for star in stars[:]: # [:] zodat je veilig kunt verwijderen tijdens het loopen
if player_rect.colliderect(star):
stars.remove(star)
score += 1
En in de tekenfunctie (zoek # TEKEN STERREN):
for star in stars:
pygame.draw.polygon(screen, YELLOW, star_points(star.centerx, star.centery, 12, 5))
star_points() is al gedefinieerd in de starter. Die berekent de punten van een 5-puntige ster.
Bovenaan het spel staat score = 0. Teken de score op het scherm (zoek # TEKEN SCORE):
score_surf = font.render(f"Sterren: {score}", True, WHITE)
screen.blit(score_surf, (10, 10))
Stap 4: 🔥 Expert: geluid en win-scherm
Nu voeg je een springgeluid toe en een win-scherm als alle sterren verzameld zijn.
Geluid laden (dit staat al klaar in de starter; controleer dat jump.wav in de sounds/ map zit):
pygame.mixer.init()
jump_snd = pygame.mixer.Sound("sounds/jump.wav")
Geluid afspelen bij springen: voeg toe aan de sprong-code:
if keys[pygame.K_SPACE] and on_ground:
vel_y = -12
jump_snd.play()
Win-scherm: voeg toe na de ster-loop:
if len(stars) == 0:
win_surf = font.render("Gewonnen! Alle sterren verzameld!", True, YELLOW)
screen.blit(win_surf, (WIDTH // 2 - win_surf.get_width() // 2, HEIGHT // 2))
pygame.display.flip()
pygame.time.wait(3000)
running = False
Showcase
Laat je spel zien aan een coach en een buddy. Kun je alle sterren verzamelen voor de tijd om is?
Dojo Defender
De Dojo Defender snapshot van vandaag bouwt verder op sessie 5:
- Parallax sterrenachtergrond — drie lagen sterren met eigen snelheid
- Particle effects — uitlaatgassen, explosiepuin, vonkjes
- Vernietigbare asteroïden — big → med → small → weg
Download de Dojo Defender starter of oplossing.
Tot de volgende keer!
“Volgende keer: klik op bugs en ZAP ze weg, met je eigen klassen.”
Neem mee naar huis
Probeer thuis één van deze uitbreidingen:
- Makkelijk: verander de kleur van de speler als hij in de lucht is.
- Middel: voeg een timer toe. De speler heeft 30 seconden om alle sterren te verzamelen.
- Lastig: voeg een vijand toe die heen en weer loopt op een platform; als de speler hem raakt, herstart het spel.
- Erg lastig: laat de speler dubbel springen (twee keer SPATIE voor een tweede sprong in de lucht).
Vastgelopen? Vraag het volgende dojo aan een coach, of probeer gewoon iets anders. Programmeren is doen.
Bekijk de cheatsheet voor deze sessie
Sessie 7: Bug Zapper
Bugs vallen van boven naar beneden. Jij schiet omhoog om ze te raken. In deze sessie leer je OOP: je schrijft je eerste eigen klasse (Bug), en daarna twee subklassen: een die slingert en een die op je duikt. Klassen zijn de bouwstenen van bijna alle grote programma’s.
Wat je vandaag leert
- Een klasse schrijven met
__init__ en eigen methoden - Overerving: een subklasse die een bestaande klasse uitbreidt
- Bullets (kogels) bijhouden in een lijst
- Botsingsdetectie tussen kogels en bugs
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py in Thonny. - Klik op Run. Je ziet een scherm met een speler onderaan, maar nog geen bugs en geen kogels.
- Problemen? Vraag een coach.
Stap 1: Bugs spawnen en schieten
De Bug-klasse
Zoek de # STAP 1 — BUG KLASSE comment en schrijf:
class Bug:
def __init__(self, x, y):
self.x = x
self.y = y
self.alive = True
def update(self):
self.y += 2 # valt naar beneden
def draw(self, screen):
pygame.draw.circle(screen, GREEN, (int(self.x), int(self.y)), 15)
# Ogen
pygame.draw.circle(screen, BLACK, (int(self.x) - 5, int(self.y) - 4), 3)
pygame.draw.circle(screen, BLACK, (int(self.x) + 5, int(self.y) - 4), 3)
Bugs laten spawnen: de starter heeft al een timer. Zoek # SPAWN BUG:
bugs.append(Bug(random.randint(30, WIDTH - 30), -20))
Schieten: zoek # SCHIET (dit staat in de event-loop bij K_SPACE):
bullets.append(pygame.Rect(player_x - 3, player_y - 20, 6, 12))
Update bullets elke frame (zoek # UPDATE BULLETS):
for b in bullets[:]:
b.y -= 10
if b.y < 0:
bullets.remove(b)
pygame.draw.rect(screen, YELLOW, b) # dit staat al klaar
Stap 2: ✅ Basic: bugs raken
Nu schrijf je de botsingsdetectie: als een kogel een bug raakt, sterft de bug.
Zoek # STAP 2 — BOTSING:
for bug in bugs[:]:
bug.update()
bug.draw(screen)
if bug.y > HEIGHT + 20:
bugs.remove(bug)
continue
bug_rect = pygame.Rect(bug.x - 15, bug.y - 15, 30, 30)
for bullet in bullets[:]:
if bullet.colliderect(bug_rect):
bug.alive = False
bullets.remove(bullet)
score += 1
break
if not bug.alive:
bugs.remove(bug)
Klik Run. Schiet op de bugs: ze verdwijnen bij een treffer!
Stap 3: ⭐ Stretch: SlingerBug
Nu maak je een subklasse: een Bug die heen en weer slingert.
import math
class SlingerBug(Bug):
def __init__(self, x, y):
super().__init__(x, y)
self.start_x = x
self.timer = 0
def update(self):
self.timer += 0.05
self.x = self.start_x + math.sin(self.timer) * 60
self.y += 1.5 # iets langzamer, maar moeilijker te raken
def draw(self, screen):
super().draw(screen)
# Oranje cirkel eromheen als visuele aanwijzing
pygame.draw.circle(screen, ORANGE, (int(self.x), int(self.y)), 18, 2)
Spawnen van SlingerBugs: voeg toe aan de spawn-code (bijv. elke 3e bug):
if random.random() < 0.3:
bugs.append(SlingerBug(random.randint(30, WIDTH - 30), -20))
else:
bugs.append(Bug(random.randint(30, WIDTH - 30), -20))
super().__init__(x, y) roept de __init__ van de ouderklas (Bug) aan, dus je hoeft self.x, self.y en self.alive niet opnieuw te schrijven.
Stap 4: 🔥 Expert: DuikBug
De DuikBug detecteert de positie van de speler en duikt er recht op af.
class DuikBug(Bug):
def __init__(self, x, y, player_x_ref):
super().__init__(x, y)
self.player_x_ref = player_x_ref # functie die huidige speler-x geeft
self.speed_x = 0
self.speed_y = 1
def update(self):
target_x = self.player_x_ref()
dx = target_x - self.x
dist = max(abs(dx), 1)
self.x += dx / dist * 2
self.y += 2.5
def draw(self, screen):
super().draw(screen)
pygame.draw.circle(screen, RED, (int(self.x), int(self.y)), 18, 2)
Spawnen: gebruik een lambda om de speler-x door te geven:
bugs.append(DuikBug(random.randint(30, WIDTH - 30), -20, lambda: player_x))
Bonus: Teken een HP-balk. Start met lives = 3 en trek er één af als een bug de onderkant haalt.
Showcase
Laat je spel zien aan een coach en een buddy. Hoeveel bugs kun je neerzappen voor je levens op zijn?
Tot de volgende keer!
“Volgende keer: een oneindige weg in de lucht, en alles SCROLT voorbij.”
Neem mee naar huis
Probeer thuis één van deze uitbreidingen:
- Makkelijk: maak bugs groter of sneller naarmate de score oploopt.
- Middel: voeg een
lives-systeem toe met 3 levens, en als een bug de onderkant haalt, verlies je er één. - Lastig: schrijf een
PantserbBug die 3 treffers nodig heeft voor hij sterft (gebruik een hp-attribuut). - Erg lastig: voeg muisbesturing toe: de speler beweegt naar de muispositie en schiet automatisch elke 0,5 seconde.
Vastgelopen? Vraag het volgende dojo aan een coach, of probeer gewoon iets anders. Programmeren is doen.
Dojo Defender: Eindbaas
Deze sessie bouw je ook verder aan Dojo Defender. Je voegt een eindbaas (boss) toe die om de 5 waves verschijnt met 3 fases.
Bekijk de Dojo Defender sessie 6 voor de instructies.
De starter en oplossing staan klaar.
Bekijk de cheatsheet voor deze sessie
Sessie 8: Sky Highway
Je schip vliegt door een eindeloze luchtweg. De achtergrond scrolt langs je heen, rode obstakels komen van rechts, en sterren geven punten. Hoe langer je overleeft, hoe sneller het wordt!
Wat je vandaag leert
- Een scrollende achtergrond maken met een
scroll_x variabele - Objecten spawnen die van rechts naar links bewegen
- Botsingsdetectie met levens
- Moeilijkheidsscaling: snelheid verhogen naarmate de score stijgt
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py in Thonny. - Klik op Run. Je ziet een statisch scherm met een schip en een luchtachtergrond, maar niks beweegt nog.
- Problemen? Vraag een coach.
Een scrollende achtergrond geeft de illusie van beweging. We tekenen de achtergrond twee keer naast elkaar en schuiven de positie elke frame op.
Zoek # STAP 1 en voeg toe:
# Beweeg achtergrond naar links
scroll_x -= speed
if scroll_x <= -WIDTH:
scroll_x = 0
# Teken achtergrond twee keer
screen.blit(bg_image, (int(scroll_x), 0))
screen.blit(bg_image, (int(scroll_x) + WIDTH, 0))
scroll_x begint op 0 en wordt elke frame kleiner. Als het -WIDTH bereikt, springen we terug naar 0: een naadloze loop.
Klik Run. De lucht scrolt nu voorbij je schip!
Stap 2: ✅ Basic: obstakels en levens
Obstakels komen van rechts en bewegen naar links. Als je ze raakt, verlies je een leven.
Obstakels updaten (zoek # STAP 2):
for obs in obstacles[:]:
obs.x -= speed
if obs.x < -obs.width:
obstacles.remove(obs)
pygame.draw.rect(screen, RED, obs)
# Botsing
if ship_rect.colliderect(obs):
obstacles.remove(obs)
lives -= 1
if lives <= 0:
running = False
Levens tekenen:
for i in range(lives):
pygame.draw.rect(screen, RED, (10 + i * 25, 10, 18, 18))
Obstakels spawnen (in de spawn-timer-event):
h = random.randint(40, 120)
obstacles.append(pygame.Rect(WIDTH, random.randint(50, HEIGHT - h - 50), 30, h))
Stap 3: ⭐ Stretch: sterren verzamelen
Sterren geven punten en verdwijnen als je ze raakt.
Zoek # STAP 3:
for star in stars[:]:
star.x -= speed
if star.x < -20:
stars.remove(star)
continue
pygame.draw.circle(screen, YELLOW, star.center, 10)
if ship_rect.colliderect(star):
stars.remove(star)
score += 1
# Score tekenen:
score_surf = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_surf, (WIDTH - 120, 10))
Spawnen van sterren (in dezelfde spawn-timer, maar minder vaak):
if random.random() < 0.4:
stars.append(pygame.Rect(WIDTH, random.randint(40, HEIGHT - 40), 20, 20))
Stap 4: 🔥 Expert: spawnen en snelheid schalen
Nu maak je de game steeds moeilijker naarmate de score stijgt.
Snelheid schalen (zoek # STAP 4):
speed = BASE_SPEED + score * 0.1
BASE_SPEED = 4 staat al bovenaan. Bij score 20 gaat alles dubbel zo snel!
Spawn-interval aanpassen: hoe hoger de score, hoe vaker nieuwe obstakels komen:
spawn_interval = max(500, 1800 - score * 30) # min. 500ms
pygame.time.set_timer(SPAWN_EVENT, spawn_interval)
Game over scherm:
if not running:
go_surf = font.render("GAME OVER", True, RED)
screen.blit(go_surf, (WIDTH // 2 - go_surf.get_width() // 2, HEIGHT // 2 - 30))
sc_surf = font.render(f"Score: {score}", True, WHITE)
screen.blit(sc_surf, (WIDTH // 2 - sc_surf.get_width() // 2, HEIGHT // 2 + 10))
pygame.display.flip()
pygame.time.wait(3000)
Showcase
Laat je spel zien aan een coach en een buddy. Wie haalt de hoogste score?
Tot de volgende keer!
“Volgende keer: een baas die terugvecht, in DRIE fases.”
Neem mee naar huis
Probeer thuis één van deze uitbreidingen:
- Makkelijk: voeg een tweede soort obstakel toe (bijv. een blauw obstakel dat hoger of lager vliegt).
- Middel: voeg power-ups toe. Vang een groene capsule voor een tijdelijk schild (het schip kan 1 keer geraakt worden).
- Lastig: laat het schip omhoog en omlaag bewegen met de pijltjestoetsen én begrens het scherm zodat het schip er niet uit vliegt.
- Erg lastig: voeg parallax-scrolling toe: een tweede laag achtergrond (wolken) die langzamer scrolt dan de eerste laag.
Vastgelopen? Vraag het volgende dojo aan een coach, of probeer gewoon iets anders. Programmeren is doen.
Dojo Defender: Jouw eigen versie
Vandaag werk je ook verder aan Dojo Defender — maar niet met stap-voor-stap instructies. Jij kiest wat je bouwt.
Download de Dojo Defender starter — dit is de complete game met alles erop en eraan (schip, vijanden, asteroïden, waves, boss). Kies een feature uit de lijst, plan hem kort met een coach, en ga aan de slag.
👉 Alles over Dojo Defender vind je op de Dojo Defender pagina.
Bekijk de cheatsheet voor deze sessie
Sessie 9: Boss Battle
De eindbaas wacht op je. Hij beweegt heen en weer, schiet kogels en wordt steeds gevaarlijker naarmate zijn HP daalt. Jij schiet terug, houdt zijn HP bij op een balk, en overleeft drie fasen. Dit is de moeilijkste sessie, en de meest bevredigende als je hem haalt.
Wat je vandaag leert
- Een HP-balk tekenen op het scherm
- Een state machine: de baas gedraagt zich anders per fase
- De baas laten schieten met een kogeltimer
- Fasen activeren op HP-drempelwaarden
Stap 0: Installeren
- Open Thonny.
- Download de starter via deze link, pak de ZIP uit en open
main.py in Thonny. - Klik op Run. Je ziet de baas bovenaan, jouw schip onderaan. Geen movement, geen kogels nog.
- Problemen? Vraag een coach.
Stap 1: Baas laten bewegen
De baas beweegt heen en weer over het scherm. Als hij de rand raakt, keert hij om.
Zoek # STAP 1 en voeg toe:
boss_rect.x += boss_speed
# Omdraaien bij de rand
if boss_rect.right >= WIDTH or boss_rect.left <= 0:
boss_speed = -boss_speed
boss_speed = 3 staat al bovenaan. Klik Run: de baas dendert van links naar rechts!
Speler bewegen en schieten (zoek # SPELER):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player_rect.left > 0:
player_rect.x -= PLAYER_SPEED
if keys[pygame.K_RIGHT] and player_rect.right < WIDTH:
player_rect.x += PLAYER_SPEED
# Schiet (zoek # SCHIET in event-loop):
player_bullets.append(pygame.Rect(player_rect.centerx - 3, player_rect.top - 15, 6, 15))
Stap 2: ✅ Basic: baas raken en HP-balk
Botsing speler-kogel met baas:
Zoek # STAP 2:
for b in player_bullets[:]:
b.y -= 8
if b.y < 0:
player_bullets.remove(b)
continue
pygame.draw.rect(screen, YELLOW, b)
if b.colliderect(boss_rect):
player_bullets.remove(b)
boss_hp -= 1
if boss_hp <= 0:
running = False # speler wint!
HP-balk tekenen (zoek # HP BALK):
# Achtergrond van de balk
pygame.draw.rect(screen, DARK_RED, (10, 10, 300, 20))
# Gevulde balk op basis van huidige HP
breedte = int(300 * boss_hp / BOSS_MAX_HP)
pygame.draw.rect(screen, RED, (10, 10, breedte, 20))
# Label
hp_surf = font.render(f"Baas HP: {boss_hp}", True, WHITE)
screen.blit(hp_surf, (320, 10))
Klik Run. Schiet op de baas: de HP-balk slinkt!
Stap 3: ⭐ Stretch: baas schiet terug
De baas schiet elke N frames een kogel naar beneden.
Zoek # STAP 3:
boss_shoot_timer += 1
if boss_shoot_timer >= boss_shoot_interval:
boss_shoot_timer = 0
boss_bullets.append(pygame.Rect(boss_rect.centerx - 4, boss_rect.bottom, 8, 16))
Baas-kogels updaten:
for b in boss_bullets[:]:
b.y += 6
if b.y > HEIGHT:
boss_bullets.remove(b)
continue
pygame.draw.rect(screen, ORANGE, b)
if b.colliderect(player_rect):
boss_bullets.remove(b)
player_lives -= 1
if player_lives <= 0:
running = False
Teken player_lives als hartjes of rode blokjes onderaan het scherm.
Stap 4: 🔥 Expert: drie fases
Nu reageert de baas op zijn HP:
- Fase 1 (HP 100 tot 50): normaal gedrag
- Fase 2 (HP 50 tot 25): sneller bewegen, vaker schieten
- Fase 3 (HP < 25): maximale snelheid, dubbele kogels
Zoek # STAP 4:
if boss_hp > 50:
boss_phase = 1
boss_speed_abs = 3
boss_shoot_interval = 60
elif boss_hp > 25:
boss_phase = 2
boss_speed_abs = 5
boss_shoot_interval = 35
else:
boss_phase = 3
boss_speed_abs = 7
boss_shoot_interval = 20
# Pas de snelheid aan zonder de richting te wisselen:
boss_speed = boss_speed_abs * (1 if boss_speed > 0 else -1)
Fase 3: dubbele kogels (voeg toe in de shoot-code):
if boss_phase == 3:
boss_bullets.append(pygame.Rect(boss_rect.left + 10, boss_rect.bottom, 8, 16))
boss_bullets.append(pygame.Rect(boss_rect.right - 18, boss_rect.bottom, 8, 16))
else:
boss_bullets.append(pygame.Rect(boss_rect.centerx - 4, boss_rect.bottom, 8, 16))
Win-scherm bij boss_hp <= 0:
screen.fill(BLACK)
win = font.render("BAAS VERSLAGEN!", True, YELLOW)
screen.blit(win, (WIDTH // 2 - win.get_width() // 2, HEIGHT // 2))
pygame.display.flip()
pygame.time.wait(3000)
Showcase
Laat je spel zien aan een coach en een buddy. Wie haalt fase 3 en overleeft?
Tot de volgende keer!
“Volgende keer: jouw eigen spel, van nul, helemaal jouw idee.”
Neem mee naar huis
Probeer thuis één van deze uitbreidingen:
- Makkelijk: verander de kleur van de baas per fase (groen → oranje → rood).
- Middel: voeg een score toe: hoe sneller je de baas verslaat, hoe meer punten.
- Lastig: laat de baas in fase 2 ook diagonale kogels schieten (schuin links en rechts).
- Erg lastig: voeg een tweede speler toe die mee kan doen met WASD-toetsen.
Vastgelopen? Vraag het volgende dojo aan een coach, of probeer gewoon iets anders. Programmeren is doen.
Bekijk de cheatsheet voor deze sessie
Sessie 10: Mijn Spel
Dit is jouw sessie. Geen vaste stappen, geen verplichte mechanics. Jij beslist wat je bouwt, en vandaag maak je het.
Jouw spel, jouw regels
In negen sessies heb je geleerd:
- Variabelen, functies en game loops
- Toetsenbord- en muisinput
- Sprites, collision detection en score
- Geluid en animatie
- Klassen en overerving
- Scrollende achtergronden, spawnen en moeilijkheidsscaling
- HP-balken, state machines en baas-AI
Al die bouwstenen liggen klaar. Vandaag combineer je ze in je eigen spel.
Kies je concept
Nog geen idee? Hier zijn wat genres om van te starten:
Dodge-game: wijk objecten uit die steeds sneller komen. Simpel maar verslavend.
Platformer: spring van platform naar platform, verzamel items, vermijd vijanden.
Shooter: schiet vijanden neer die van boven of van de zijkant komen.
Puzzelgame: schuif blokjes, verbind punten, of los een patroon op.
Racegame: ontwerp een parcours en beweeg zo snel mogelijk naar de finish.
Vertel een verhaal: geen score, geen levens. Laat de speler klikken en keuzes maken.
Je mag ook iets combineren: een shooter met puzzelelementen, een platformer met een baas aan het einde. Alles mag.
Plan je spel
Vóór je code schrijft, beantwoord deze drie vragen:
- Wat doet de speler? (bewegen, schieten, springen, klikken, …)
- Wat is het doel? (score halen, de baas verslaan, het einde bereiken, …)
- Wat maakt het moeilijk? (vijanden, obstakels, een timer, …)
Schrijf je antwoorden op een papiertje of in een comment bovenaan je code. Dit helpt je gefocust te blijven als je vastloopt.
Animatie: sprite wisselen per frame
Wil je een loopanimatie, een explosie of een knipperend object? Maak een lijst met afbeeldingsnamen en wissel actor.image elke N milliseconden. De demo hieronder laat zien hoe dat werkt: gebruik de schuifbalk om de snelheid aan te passen en de knop om te pauzeren:
In Python gebruik je dan een lijst met afbeeldingsnamen en een timer:
frames = ['lopen_1', 'lopen_2', 'lopen_3', 'lopen_4']
anim_timer = 0
FRAME_DUUR = 10 # frames (bij 60 fps = ~167 ms)
def update():
global anim_timer
anim_timer += 1
speler.image = frames[(anim_timer // FRAME_DUUR) % len(frames)]
Aan de slag
Download de starter via deze link. De starter heeft:
- Een werkende pygame game loop
- Een lege
draw()- en update()-sectie - Kleur-constanten en een lettertypevariabele klaar
- Comments die aangeven waar je wat kunt plaatsen
Open main.py en begin met Stap 1 van je eigen plan. De cheatsheet op deze pagina heeft alle patronen van de vorige sessies bij de hand.
Vastgelopen? Vraag een coach. Beschrijf wat je wilt bereiken, niet alleen wat niet werkt. Dan kunnen we samen de beste aanpak bedenken.
Te snel klaar? Voeg geluid toe, maak een start-scherm, of voeg een tweede speler toe.
Showcase
Aan het einde van de sessie presenteert iedereen zijn spel. Je hoeft het niet af te hebben. Laat zien wat je gemaakt hebt en vertel:
- Wat is het concept van je spel?
- Welke techniek uit een vorige sessie heb je gebruikt?
- Wat zou je nog willen toevoegen als je meer tijd had?
Wat nu?
CoderDojo stopt na tien sessies. Zelf bouwen stopt niet.
Blijf bouwen. Kleine projectjes leren je meer dan grote cursussen. Maak een spel voor je broer of zus, je huisdier, of gewoon voor jezelf.
Inspiratie nodig?
CoderDojo komt terug. Jij ook?
Blijf bouwen!
Bekijk de cheatsheet voor deze sessie