10.9 Pymunk: een vloer toevoegen
De voorbeelden in dit hoofdstuk draaien niet in de online speeltuin. Een pygame-ce-programma schrijft zijn eigen game-loop, en die is in de browser niet meer te stoppen. Draai ze op je eigen computer, in Thonny of VS Code — zie installatie.
In de vorige les viel de bal naar beneden en verdween van het scherm. Met een vloer eronder kan hij stuiteren.
Een static body
Een vloer is een vorm die niet beweegt. In pymunk maak je die met een static body:
vloer_body = pymunk.Body(body_type=pymunk.Body.STATIC)
Een STATIC body beweegt nooit, ongeacht hoeveel kracht erop wordt uitgeoefend. Net zoals can_move=False in coderius-play.
Een vloer als Segment
vloer_shape = pymunk.Segment(vloer_body, (0, 550), (800, 550), 5)
Een Segment is een lijn van punt (0, 550) naar punt (800, 550) met dikte 5. Precies wat je nodig hebt voor een vloer.
Elasticity: stuiteren
bal_shape.elasticity = 0.8
vloer_shape.elasticity = 0.8
elasticity bepaalt hoe hard iets terugkaatst:
1.0= volledig terugkaatsen (geen energie verloren)0.5= half terugkaatsen0.0= niet terugkaatsen (plof)
Het volledige programma
import pygame
import pymunk
pygame.init()
scherm = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = (0, 500)
# Bal
bal_body = pymunk.Body(1, pymunk.moment_for_circle(1, 0, 20))
bal_body.position = (400, 50)
bal_shape = pymunk.Circle(bal_body, 20)
bal_shape.elasticity = 0.8
space.add(bal_body, bal_shape)
# Vloer (static)
vloer_body = pymunk.Body(body_type=pymunk.Body.STATIC)
vloer_shape = pymunk.Segment(vloer_body, (0, 550), (800, 550), 5)
vloer_shape.elasticity = 0.8
space.add(vloer_body, vloer_shape)
actief = True
while actief:
for event in pygame.event.get():
if event.type == pygame.QUIT:
actief = False
space.step(1 / 60)
scherm.fill((30, 30, 30))
bal_x = int(bal_body.position.x)
bal_y = int(bal_body.position.y)
pygame.draw.circle(scherm, (0, 200, 255), (bal_x, bal_y), 20)
pygame.draw.line(scherm, (255, 255, 255), (0, 550), (800, 550), 5)
pygame.display.flip()
clock.tick(60)
pygame.quit()
De bal stuitert nu op de vloer.
Opdracht 10.9.a: Elasticity uitproberen
Verander de elasticity van de bal en de vloer. Probeer:
elasticity = 1.0op beide. Wat gebeurt er?elasticity = 0.0op beide. Wat gebeurt er?elasticity = 1.0op de bal en0.0op de vloer. Wat gebeurt er?
Klik hier voor de oplossing.
- De bal stuitert eindeloos op dezelfde hoogte (geen energieverlies)
- De bal valt en blijft liggen (geen stuitering)
- De bal stuitert nog steeds, maar minder hoog. De elasticity van een botsing wordt berekend uit beide vormen.
Opdracht 10.9.b: Muren toevoegen
Voeg naast de vloer ook een linker- en rechtermuur toe, zodat de bal niet van het scherm kan vallen.
Klik hier voor een tip.
Maak nog twee Segments: eentje van (0, 0) naar (0, 600) (linkermuur) en eentje van (800, 0) naar (800, 600) (rechtermuur). Gebruik dezelfde vloer_body (een static body kan meerdere shapes hebben).
Klik hier voor de oplossing.
Voeg dit toe na de vloer:
# Muren
linker_muur = pymunk.Segment(vloer_body, (0, 0), (0, 600), 5)
linker_muur.elasticity = 0.8
rechter_muur = pymunk.Segment(vloer_body, (800, 0), (800, 600), 5)
rechter_muur.elasticity = 0.8
space.add(linker_muur, rechter_muur)
En teken ze in de game loop:
pygame.draw.line(scherm, (255, 255, 255), (0, 0), (0, 600), 5)
pygame.draw.line(scherm, (255, 255, 255), (800, 0), (800, 600), 5)