Ga naar hoofdinhoud

10.9 Pymunk: een vloer toevoegen

Online speeltuin

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 terugkaatsen
  • 0.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:

  1. elasticity = 1.0 op beide. Wat gebeurt er?
  2. elasticity = 0.0 op beide. Wat gebeurt er?
  3. elasticity = 1.0 op de bal en 0.0 op de vloer. Wat gebeurt er?
Klik hier voor de oplossing.
  1. De bal stuitert eindeloos op dezelfde hoogte (geen energieverlies)
  2. De bal valt en blijft liggen (geen stuitering)
  3. 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)