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

  1. Open Thonny.
  2. Download de starter via deze link, pak de ZIP uit en open main.py in Thonny.
  3. Klik op Run. Je ziet een scherm met een speler onderaan, maar nog geen bugs en geen kogels.
  4. 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:

  1. Makkelijk: maak bugs groter of sneller naarmate de score oploopt.
  2. Middel: voeg een lives-systeem toe met 3 levens, en als een bug de onderkant haalt, verlies je er één.
  3. Lastig: schrijf een PantserbBug die 3 treffers nodig heeft voor hij sterft (gebruik een hp-attribuut).
  4. 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