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.pyin 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 klaarStap 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
PantserbBugdie 3 treffers nodig heeft voor hij sterft (gebruik eenhp-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.