1 2022-02-14: Pygame

1.1 Herhaling

Vorig jaar gebruikten we Pygame om een eenvoudige side-scrolling game te implementeren.

In onderstaand stukje code herhalen we de belangrijkste concepten:

 1import pygame
 2
 3WIDTH = 800
 4HEIGHT = 600
 5
 6pygame.init()
 7screen = pygame.display.set_mode((WIDTH, HEIGHT))
 8clock = pygame.time.Clock()
 9
10player_img = pygame.image.load("ship.png").convert_alpha()
11bullet_img = pygame.image.load("bullet.png").convert_alpha()
12
13player_x = WIDTH / 2
14player_y = 500
15player_xchange = 0
16PLAYER_SPEED = 5
17
18bullet_x = 0
19bullet_y = 0
20bullet_ychange = -5
21
22running = True
23while running:
24    for event in pygame.event.get():
25        if event.type == pygame.QUIT:
26            running = False
27        elif event.type == pygame.KEYDOWN:
28            if event.key == pygame.K_SPACE:
29                bullet_x = player_x
30                bullet_y = player_y
31            if event.key == pygame.K_LEFT:
32                player_xchange -= PLAYER_SPEED
33            if event.key == pygame.K_RIGHT:
34                player_xchange += PLAYER_SPEED
35        elif event.type == pygame.KEYUP:
36            if event.key == pygame.K_LEFT:
37                player_xchange = 0
38            elif event.key == pygame.K_RIGHT:
39                player_xchange = 0
40
41    player_x += player_xchange
42    bullet_y += bullet_ychange
43
44    screen.fill("black")
45    screen.blit(player_img, (player_x, player_y))
46
47    screen.blit(bullet_img, (bullet_x, bullet_y))
48
49    pygame.display.flip()
50
51    # Wacht zodanig dat we maximal 60 FPS halen
52    clock.tick(60)

1.1.1 Variabele duplicatie per kogel

Stel nu dat we gelijktijdig twee kogels willen kunnen schieten:

 1import pygame
 2
 3WIDTH = 800
 4HEIGHT = 600
 5
 6pygame.init()
 7
 8# Maak een venster aan met de opgegeven resolutie
 9screen = pygame.display.set_mode((WIDTH, HEIGHT))
10
11clock = pygame.time.Clock()
12
13# Laad de "sprites" (afbeeldingen) in
14player_img = pygame.image.load("ship.png").convert_alpha()
15bullet_img = pygame.image.load("bullet.png").convert_alpha()
16
17# De positie van de speler
18player_x = WIDTH / 2
19player_y = 500
20
21# De verplaatsing van de speler op de X-as
22player_xchange = 0
23PLAYER_SPEED = 5
24
25# De positie van kogel 1
26bullet1_x = 0
27bullet1_y = 0
28# De verplaatsing van de kogel 1 op de Y-as
29bullet1_ychange = -5
30
31# De positie van kogel 2
32bullet2_x = 0
33bullet2_y = 0
34# De verplaatsing van de kogel 2 op de Y-as
35bullet2_ychange = -5
36
37# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
38running = True
39while running:
40    for event in pygame.event.get():
41        if event.type == pygame.QUIT:
42            running = False
43        elif event.type == pygame.KEYDOWN:
44            if event.key == pygame.K_SPACE:
45                # Als de speler op de spatiebalk drukt, plaats dan een kogel
46                # op de positie van de speler
47                bullet1_x = player_x
48                bullet1_y = player_y
49                bullet2_x = player_x + 50
50                bullet2_y = player_y
51            if event.key == pygame.K_LEFT:
52                # Als de speler op het linkerpijltje drukt
53                # stel dan de verplaatsing van de speler in naar links
54                player_xchange -= PLAYER_SPEED
55            if event.key == pygame.K_RIGHT:
56                # Als de speler op het rechterpijltje drukt
57                # stel dan de verplaatsing van de speler in naar rechts
58                player_xchange += PLAYER_SPEED
59        elif event.type == pygame.KEYUP:
60            if event.key == pygame.K_LEFT:
61                # Als de speler het linkerpijltje loslaat
62                # stel dan de verplaatsingsnelheid in op 0
63                player_xchange = 0
64            elif event.key == pygame.K_RIGHT:
65                # Als de speler het rechterpijltje loslaat
66                # stel dan de verplaatsingsnelheid in op 0
67                player_xchange = 0
68
69    # Verplaats de speler
70    player_x += player_xchange
71    # Verplaats de kogels
72    bullet1_y += bullet1_ychange
73    bullet2_y += bullet2_ychange
74
75    # Veeg het scherm uit
76    screen.fill("black")
77
78    # Teken de speler
79    screen.blit(player_img, (player_x, player_y))
80
81    # Teken kogel 1 en 2
82    screen.blit(bullet_img, (bullet1_x, bullet1_y))
83    screen.blit(bullet_img, (bullet2_x, bullet2_y))
84
85    # Update het scherm
86    pygame.display.flip()
87
88    # Wacht zodanig dat we maximal 60 FPS halen
89    clock.tick(60)

Stel nu dat je 5 kogels willen kunnen schieten:

 1# ...
 2
 3# De positie van kogel 1
 4bullet1_x = 0
 5bullet1_y = 0
 6# De verplaatsing van de kogel 1 op de Y-as
 7bullet1_ychange = -5
 8
 9# De positie van kogel 2
10bullet2_x = 0
11bullet2_y = 0
12# De verplaatsing van de kogel 2 op de Y-as
13bullet2_ychange = -5
14
15# De positie van kogel 3
16bullet3_x = 0
17bullet3_y = 0
18# De verplaatsing van de kogel 3 op de Y-as
19bullet3_ychange = -5
20
21# De positie van kogel 4
22bullet4_x = 0
23bullet4_y = 0
24# De verplaatsing van de kogel 4 op de Y-as
25bullet4_ychange = -5
26
27# De positie van kogel 5
28bullet5_x = 0
29bullet5_y = 0
30# De verplaatsing van de kogel 5 op de Y-as
31bullet5_ychange = -5
32    # ...
33
34    # Verplaats de kogels
35    bullet1_y += bullet1_ychange
36    bullet2_y += bullet2_ychange
37    bullet3_y += bullet3_ychange
38    bullet4_y += bullet4_ychange
39    bullet5_y += bullet5_ychange
40
41    # ...
42
43    # Teken kogel 1 en 2
44    screen.blit(bullet_img, (bullet1_x, bullet1_y))
45    screen.blit(bullet_img, (bullet2_x, bullet2_y))
46    screen.blit(bullet_img, (bullet3_x, bullet3_y))
47    screen.blit(bullet_img, (bullet4_x, bullet4_y))
48    screen.blit(bullet_img, (bullet5_x, bullet5_y))
49    
50    # ...

Stel nu dat je 100 kogels willen kunnen schieten… Het mag duidelijk zijn dat dit niet de correcte aanpak is, omdat je enorm veel code dient te schrijven of dupliceren.

1.1.2 Lijsten van kogels

We losten dit vorig jaar op, door een lijst van kogels bij te houden. Deze lijst bevat per kogel een lijst. Stel dat we bijvoorbeeld 3 kogels afvuurden terwijl de speler op positie (100, 240) stond. Je zou dan deze lijst met kogels hebben:

1bullets = [
2    [100, 240],
3    [100, 240],
4    [100, 240],
5]

Waarschijnlijker zouden de coordinaten van de kogels niet allemaal hetzelfde zijn:

1bullets = [
2    [20, 120],
3    [100, 239],
4    [230, 439],
5]

Een voorbeeld van de code die gebruik maakt van een lijst van kogels:

 1import pygame
 2
 3WIDTH = 800
 4HEIGHT = 600
 5
 6pygame.init()
 7
 8# Maak een venster aan met de opgegeven resolutie
 9screen = pygame.display.set_mode((WIDTH, HEIGHT))
10
11clock = pygame.time.Clock()
12
13# Laad de "sprites" (afbeeldingen) in
14player_img = pygame.image.load("ship.png").convert_alpha()
15bullet_img = pygame.image.load("bullet.png").convert_alpha()
16
17# De positie van de speler
18player_x = WIDTH / 2
19player_y = 500
20
21# De verplaatsing van de speler op de X-as
22player_xchange = 0
23PLAYER_SPEED = 5
24
25# De posities van alle kogels als een lijst van X- en Y-coordinaten
26bullets = []
27# De verplaatsing van een kogel op de Y-as
28bullet_ychange = -5
29
30
31# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
32running = True
33while running:
34    for event in pygame.event.get():
35        if event.type == pygame.QUIT:
36            running = False
37        elif event.type == pygame.KEYDOWN:
38            if event.key == pygame.K_SPACE:
39                # Als de speler op de spatiebalk drukt,
40                # maak dan een nieuwe lijst aan met de X- en Y-coordinaat
41                # van de nieuwe kogel
42                nieuwe_kogel = [player_x, player_y]
43                # Voeg deze lijst toe aan de lijst van kogels
44                bullets.append(nieuwe_kogel)
45            if event.key == pygame.K_LEFT:
46                # Als de speler op het linkerpijltje drukt
47                # stel dan de verplaatsing van de speler in naar links
48                player_xchange -= PLAYER_SPEED
49            if event.key == pygame.K_RIGHT:
50                # Als de speler op het rechterpijltje drukt
51                # stel dan de verplaatsing van de speler in naar rechts
52                player_xchange += PLAYER_SPEED
53        elif event.type == pygame.KEYUP:
54            if event.key == pygame.K_LEFT:
55                # Als de speler het linkerpijltje loslaat
56                # stel dan de verplaatsingsnelheid in op 0
57                player_xchange = 0
58            elif event.key == pygame.K_RIGHT:
59                # Als de speler het rechterpijltje loslaat
60                # stel dan de verplaatsingsnelheid in op 0
61                player_xchange = 0
62
63    # Verplaats de speler
64    player_x += player_xchange
65
66    # Verplaats de kogels door voor ieder element in de lijst van
67    # kogels de Y-positie aan te passen
68    for bullet in bullets:
69        # bullet is hier 1 kogel, voorgesteld door een lijst met 2 elementen
70        # b.v. [100, 200] voor een kogel op X-positie 100, Y-positie 200
71        # We passen enkel de Y-positie aan, omdat de kogel enkel verticaal
72        # beweegt
73        bullet[1] += bullet_ychange
74
75    # Veeg het scherm uit
76    screen.fill("black")
77
78    # Teken de speler
79    screen.blit(player_img, (player_x, player_y))
80
81    # Teken alle kogels in de lijst
82    for bullet in bullets:
83        screen.blit(bullet_img, (bullet[0], bullet[1]))
84
85    # Update het scherm
86    pygame.display.flip()
87
88    # Wacht zodanig dat we maximal 60 FPS halen
89    clock.tick(60)

Een probleem met deze code is echter, dat de code voor de kogels verspreid zit over de hele broncode.

1.1.3 Introductie vijanden

Als we nu een vijand introduceren, zien we dat de code voor het bijhouden van de positie van de vijand, het tekenen van de vijand, etc sterk lijkt op de code die gebruikt werd voor dezelfde functionaliteit van de kogels:

  1import pygame
  2
  3WIDTH = 800
  4HEIGHT = 600
  5
  6pygame.init()
  7
  8# Maak een venster aan met de opgegeven resolutie
  9screen = pygame.display.set_mode((WIDTH, HEIGHT))
 10
 11clock = pygame.time.Clock()
 12
 13# Laad de "sprites" (afbeeldingen) in
 14player_img = pygame.image.load("ship.png").convert_alpha()
 15bullet_img = pygame.image.load("bullet.png").convert_alpha()
 16enemy_img = pygame.image.load("enemyship.png").convert_alpha()
 17
 18# De positie van de speler
 19player_x = WIDTH / 2
 20player_y = 500
 21
 22# De verplaatsing van de speler op de X-as
 23player_xchange = 0
 24PLAYER_SPEED = 5
 25
 26# De posities van alle kogels als een lijst van X- en Y-coordinaten
 27bullets = []
 28# De verplaatsing van een kogel op de Y-as
 29bullet_ychange = -5
 30
 31# Positie van de vijand, en verplaatsing van de vijand
 32enemy_alive = True
 33enemy_x = WIDTH - 200
 34enemy_y = 0
 35enemy_x_change = 0
 36enemy_y_change = 1
 37
 38# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
 39running = True
 40while running:
 41    for event in pygame.event.get():
 42        if event.type == pygame.QUIT:
 43            running = False
 44        elif event.type == pygame.KEYDOWN:
 45            if event.key == pygame.K_SPACE:
 46                # Als de speler op de spatiebalk drukt,
 47                # maak dan een nieuwe lijst aan met de X- en Y-coordinaat
 48                # van de nieuwe kogel
 49                nieuwe_kogel = [player_x, player_y]
 50                # Voeg deze lijst toe aan de lijst van kogels
 51                bullets.append(nieuwe_kogel)
 52            if event.key == pygame.K_LEFT:
 53                # Als de speler op het linkerpijltje drukt
 54                # stel dan de verplaatsing van de speler in naar links
 55                player_xchange -= PLAYER_SPEED
 56            if event.key == pygame.K_RIGHT:
 57                # Als de speler op het rechterpijltje drukt
 58                # stel dan de verplaatsing van de speler in naar rechts
 59                player_xchange += PLAYER_SPEED
 60        elif event.type == pygame.KEYUP:
 61            if event.key == pygame.K_LEFT:
 62                # Als de speler het linkerpijltje loslaat
 63                # stel dan de verplaatsingsnelheid in op 0
 64                player_xchange = 0
 65            elif event.key == pygame.K_RIGHT:
 66                # Als de speler het rechterpijltje loslaat
 67                # stel dan de verplaatsingsnelheid in op 0
 68                player_xchange = 0
 69
 70    # Verplaats de speler
 71    player_x += player_xchange
 72
 73    if enemy_alive:
 74        # Verplaats de vijand
 75        enemy_x += enemy_x_change
 76        enemy_y += enemy_y_change
 77
 78        # Als de vijand buiten het scherm gaat,
 79        # plaats hem dan terug bovenaan het scherm
 80        if enemy_y > HEIGHT:
 81            enemy_y = 0
 82
 83    # Verplaats de kogels door voor ieder element in de lijst van
 84    # kogels de Y-positie aan te passen
 85    for bullet in bullets:
 86        # bullet is hier 1 kogel, voorgesteld door een lijst met 2 elementen
 87        # b.v. [100, 200] voor een kogel op X-positie 100, Y-positie 200
 88        # We passen enkel de Y-positie aan, omdat de kogel enkel verticaal
 89        # beweegt
 90        bullet[1] += bullet_ychange
 91
 92    # Veeg het scherm uit
 93    screen.fill("black")
 94
 95    # Teken de speler
 96    screen.blit(player_img, (player_x, player_y))
 97
 98    # Teken de vijand
 99    screen.blit(enemy_img, (enemy_x, enemy_y))
100
101    # Teken alle kogels in de lijst
102    for bullet in bullets:
103        screen.blit(bullet_img, (bullet[0], bullet[1]))
104
105    # Update het scherm
106    pygame.display.flip()
107
108    # Wacht zodanig dat we maximal 60 FPS halen
109    clock.tick(60)

Stel nu dat je meerdere vijanden wil tonen? Je zou net zoals voor de kogels lijsten van vijanden kunnen bijhouden.

  1import pygame
  2
  3
  4WIDTH = 800
  5HEIGHT = 600
  6
  7pygame.init()
  8
  9# Maak een venster aan met de opgegeven resolutie
 10screen = pygame.display.set_mode((WIDTH, HEIGHT))
 11
 12clock = pygame.time.Clock()
 13
 14# Laad de "sprites" (afbeeldingen) in
 15player_img = pygame.image.load("ship.png").convert_alpha()
 16bullet_img = pygame.image.load("bullet.png").convert_alpha()
 17enemy_img = pygame.image.load("enemyship.png").convert_alpha()
 18
 19# De positie van de speler
 20player_x = WIDTH / 2
 21player_y = 500
 22
 23# De verplaatsing van de speler op de X-as
 24player_xchange = 0
 25PLAYER_SPEED = 5
 26
 27# De posities van alle kogels als een lijst van X- en Y-coordinaten
 28bullets = []
 29# De verplaatsing van een kogel op de Y-as
 30bullet_ychange = -5
 31
 32# Positie van de vijand, en verplaatsing van de vijand
 33enemies = []
 34enemy_x_change = 0
 35enemy_y_change = 1
 36
 37# Voeg een vijand toe op positie (100, 0)
 38enemies.append([100, 0])
 39# Voeg een vijand toe op positie (400, 0)
 40enemies.append([400, 0])
 41
 42# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
 43running = True
 44while running:
 45    for event in pygame.event.get():
 46        if event.type == pygame.QUIT:
 47            running = False
 48        elif event.type == pygame.KEYDOWN:
 49            if event.key == pygame.K_SPACE:
 50                # Als de speler op de spatiebalk drukt,
 51                # maak dan een nieuwe lijst aan met de X- en Y-coordinaat
 52                # van de nieuwe kogel
 53                nieuwe_kogel = [player_x, player_y]
 54                # Voeg deze lijst toe aan de lijst van kogels
 55                bullets.append(nieuwe_kogel)
 56            if event.key == pygame.K_LEFT:
 57                # Als de speler op het linkerpijltje drukt
 58                # stel dan de verplaatsing van de speler in naar links
 59                player_xchange -= PLAYER_SPEED
 60            if event.key == pygame.K_RIGHT:
 61                # Als de speler op het rechterpijltje drukt
 62                # stel dan de verplaatsing van de speler in naar rechts
 63                player_xchange += PLAYER_SPEED
 64        elif event.type == pygame.KEYUP:
 65            if event.key == pygame.K_LEFT:
 66                # Als de speler het linkerpijltje loslaat
 67                # stel dan de verplaatsingsnelheid in op 0
 68                player_xchange = 0
 69            elif event.key == pygame.K_RIGHT:
 70                # Als de speler het rechterpijltje loslaat
 71                # stel dan de verplaatsingsnelheid in op 0
 72                player_xchange = 0
 73
 74    # Verplaats de speler
 75    player_x += player_xchange
 76    for enemy in enemies:
 77        # Verplaats de vijand
 78        enemy[0] += enemy_x_change
 79        enemy[1] += enemy_y_change
 80
 81        # Als de vijand buiten het scherm gaat,
 82        # plaats hem dan terug bovenaan het scherm
 83        if enemy[1] > HEIGHT:
 84            enemy[1] = 0
 85
 86    # Verplaats de kogels door voor ieder element in de lijst van
 87    # kogels de Y-positie aan te passen
 88    for bullet in bullets:
 89        # bullet is hier 1 kogel, voorgesteld door een lijst met 2 elementen
 90        # b.v. [100, 200] voor een kogel op X-positie 100, Y-positie 200
 91        # We passen enkel de Y-positie aan, omdat de kogel enkel verticaal
 92        # beweegt
 93        bullet[1] += bullet_ychange
 94
 95    # Veeg het scherm uit
 96    screen.fill("black")
 97
 98    # Teken de speler
 99    screen.blit(player_img, (player_x, player_y))
100
101    # Teken de vijand
102    for enemy_x, enemy_y in enemies:
103        screen.blit(enemy_img, (enemy_x, enemy_y))
104
105    # Teken alle kogels in de lijst
106    for bullet in bullets:
107        screen.blit(bullet_img, (bullet[0], bullet[1]))
108
109    # Update het scherm
110    pygame.display.flip()
111
112    # Wacht zodanig dat we maximal 60 FPS halen
113    clock.tick(60)

Als we ook willen bijhouden of de vijanden nog leven wordt dit:

  1import pygame
  2
  3
  4WIDTH = 800
  5HEIGHT = 600
  6
  7pygame.init()
  8
  9# Maak een venster aan met de opgegeven resolutie
 10screen = pygame.display.set_mode((WIDTH, HEIGHT))
 11
 12clock = pygame.time.Clock()
 13
 14# Laad de "sprites" (afbeeldingen) in
 15player_img = pygame.image.load("ship.png").convert_alpha()
 16bullet_img = pygame.image.load("bullet.png").convert_alpha()
 17enemy_img = pygame.image.load("enemyship.png").convert_alpha()
 18
 19# De positie van de speler
 20player_x = WIDTH / 2
 21player_y = 500
 22
 23# De verplaatsing van de speler op de X-as
 24player_xchange = 0
 25PLAYER_SPEED = 5
 26
 27# De posities van alle kogels als een lijst van X- en Y-coordinaten
 28bullets = []
 29# De verplaatsing van een kogel op de Y-as
 30bullet_ychange = -5
 31
 32# Positie van de vijand, en verplaatsing van de vijand
 33enemies = []
 34enemy_x_change = 0
 35enemy_y_change = 1
 36
 37# Voeg een vijand toe op positie (100, 0)
 38enemies.append([100, 0, True])
 39# Voeg een vijand toe op positie (400, 0)
 40enemies.append([400, 0, True])
 41
 42# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
 43running = True
 44while running:
 45    for event in pygame.event.get():
 46        if event.type == pygame.QUIT:
 47            running = False
 48        elif event.type == pygame.KEYDOWN:
 49            if event.key == pygame.K_SPACE:
 50                # Als de speler op de spatiebalk drukt,
 51                # maak dan een nieuwe lijst aan met de X- en Y-coordinaat
 52                # van de nieuwe kogel
 53                nieuwe_kogel = [player_x, player_y]
 54                # Voeg deze lijst toe aan de lijst van kogels
 55                bullets.append(nieuwe_kogel)
 56            if event.key == pygame.K_LEFT:
 57                # Als de speler op het linkerpijltje drukt
 58                # stel dan de verplaatsing van de speler in naar links
 59                player_xchange -= PLAYER_SPEED
 60            if event.key == pygame.K_RIGHT:
 61                # Als de speler op het rechterpijltje drukt
 62                # stel dan de verplaatsing van de speler in naar rechts
 63                player_xchange += PLAYER_SPEED
 64        elif event.type == pygame.KEYUP:
 65            if event.key == pygame.K_LEFT:
 66                # Als de speler het linkerpijltje loslaat
 67                # stel dan de verplaatsingsnelheid in op 0
 68                player_xchange = 0
 69            elif event.key == pygame.K_RIGHT:
 70                # Als de speler het rechterpijltje loslaat
 71                # stel dan de verplaatsingsnelheid in op 0
 72                player_xchange = 0
 73
 74    # Verplaats de speler
 75    player_x += player_xchange
 76    for enemy in enemies:
 77        # Als de vijand nog leeft
 78        if enemy[2]:
 79            # Verplaats de vijand
 80            enemy[0] += enemy_x_change
 81            enemy[1] += enemy_y_change
 82
 83            # Als de vijand buiten het scherm gaat,
 84            # plaats hem dan terug bovenaan het scherm
 85            if enemy[1] > HEIGHT:
 86                enemy[1] = 0
 87
 88    # Verplaats de kogels door voor ieder element in de lijst van
 89    # kogels de Y-positie aan te passen
 90    for bullet in bullets:
 91        # bullet is hier 1 kogel, voorgesteld door een lijst met 2 elementen
 92        # b.v. [100, 200] voor een kogel op X-positie 100, Y-positie 200
 93        # We passen enkel de Y-positie aan, omdat de kogel enkel verticaal
 94        # beweegt
 95        bullet[1] += bullet_ychange
 96
 97    # Veeg het scherm uit
 98    screen.fill("black")
 99
100    # Teken de speler
101    screen.blit(player_img, (player_x, player_y))
102
103    # Teken de vijand
104    for enemy_x, enemy_y, enemy_alive in enemies:
105        if enemy_alive:
106            screen.blit(enemy_img, (enemy_x, enemy_y))
107
108    # Teken alle kogels in de lijst
109    for bullet in bullets:
110        screen.blit(bullet_img, (bullet[0], bullet[1]))
111
112    # Update het scherm
113    pygame.display.flip()
114
115    # Wacht zodanig dat we maximal 60 FPS halen
116    clock.tick(60)

1.1.4 Introductie classes

Zoals we reeds eerder aangaven, zit de code voor de kogels verspreid over heel de code.

We introduceren nu een “Bullet” class, waarin we alle code van de Bullet groeperen.

  1import pygame
  2
  3WIDTH = 800
  4HEIGHT = 600
  5
  6
  7class Bullet:
  8    def __init__(self, x, y):
  9        # De positie van de speler
 10        self.x = x
 11        self.y = y
 12        # De verplaatsing van een kogel op de Y-as
 13        self.y_change = -5
 14
 15    def update(self):
 16        # We passen enkel de Y-positie aan, omdat de kogel enkel verticaal
 17        # beweegt
 18        self.y += self.y_change
 19
 20    def blit(self, screen, img):
 21        screen.blit(img, (self.x, self.y))
 22
 23
 24pygame.init()
 25
 26# Maak een venster aan met de opgegeven resolutie
 27screen = pygame.display.set_mode((WIDTH, HEIGHT))
 28
 29clock = pygame.time.Clock()
 30
 31# Laad de "sprites" (afbeeldingen) in
 32player_img = pygame.image.load("ship.png").convert_alpha()
 33bullet_img = pygame.image.load("bullet.png").convert_alpha()
 34enemy_img = pygame.image.load("enemyship.png").convert_alpha()
 35
 36# De positie van de speler
 37player_x = WIDTH / 2
 38player_y = 500
 39
 40# De verplaatsing van de speler op de X-as
 41player_xchange = 0
 42PLAYER_SPEED = 5
 43
 44# De posities van alle kogels als een lijst van X- en Y-coordinaten
 45bullets = []
 46
 47# Positie van de vijand, en verplaatsing van de vijand
 48enemies = []
 49enemy_x_change = 0
 50enemy_y_change = 1
 51
 52# Voeg een vijand toe op positie (100, 0)
 53enemies.append([100, 0, True])
 54# Voeg een vijand toe op positie (400, 0)
 55enemies.append([400, 0, True])
 56
 57# Een variabele die we op False kunnen zetten om uit de while-lus te geraken
 58running = True
 59while running:
 60    for event in pygame.event.get():
 61        if event.type == pygame.QUIT:
 62            running = False
 63        elif event.type == pygame.KEYDOWN:
 64            if event.key == pygame.K_SPACE:
 65                # Als de speler op de spatiebalk drukt,
 66                # maak dan een nieuwe lijst aan met de X- en Y-coordinaat
 67                # van de nieuwe kogel
 68                nieuwe_kogel = Bullet(x=player_x, y=player_y)
 69                # Voeg deze lijst toe aan de lijst van kogels
 70                bullets.append(nieuwe_kogel)
 71            if event.key == pygame.K_LEFT:
 72                # Als de speler op het linkerpijltje drukt
 73                # stel dan de verplaatsing van de speler in naar links
 74                player_xchange -= PLAYER_SPEED
 75            if event.key == pygame.K_RIGHT:
 76                # Als de speler op het rechterpijltje drukt
 77                # stel dan de verplaatsing van de speler in naar rechts
 78                player_xchange += PLAYER_SPEED
 79        elif event.type == pygame.KEYUP:
 80            if event.key == pygame.K_LEFT:
 81                # Als de speler het linkerpijltje loslaat
 82                # stel dan de verplaatsingsnelheid in op 0
 83                player_xchange = 0
 84            elif event.key == pygame.K_RIGHT:
 85                # Als de speler het rechterpijltje loslaat
 86                # stel dan de verplaatsingsnelheid in op 0
 87                player_xchange = 0
 88
 89    # Verplaats de speler
 90    player_x += player_xchange
 91    for enemy in enemies:
 92        # Als de vijand nog leeft
 93        if enemy[2]:
 94            # Verplaats de vijand
 95            enemy[0] += enemy_x_change
 96            enemy[1] += enemy_y_change
 97
 98            # Als de vijand buiten het scherm gaat,
 99            # plaats hem dan terug bovenaan het scherm
100            if enemy[1] > HEIGHT:
101                enemy[1] = 0
102
103    # Verplaats de kogels door voor ieder element 
104    # de update() functie uit te voeren.
105    for bullet in bullets:
106        bullet.update()
107
108    # Veeg het scherm uit
109    screen.fill("black")
110
111    # Teken de speler
112    screen.blit(player_img, (player_x, player_y))
113
114    # Teken de vijand
115    for enemy_x, enemy_y, enemy_alive in enemies:
116        if enemy_alive:
117            screen.blit(enemy_img, (enemy_x, enemy_y))
118
119    # Teken alle kogels in de lijst
120    for bullet in bullets:
121        bullet.blit(screen, bullet_img)
122
123    # Update het scherm
124    pygame.display.flip()
125
126    # Wacht zodanig dat we maximal 60 FPS halen
127    clock.tick(60)

1.1.5 Opgave: Enemy class

Introduceer een class Enemy gelijkaardig aan de class Bullet.

1.1.6 Inheritance

We zien nu dat de code van de Enemy class grotendeels gelijk is aan de code van de Bullet class. We dienen code duplicatie te vermijden, dus we introduceren een nieuwe class Entity die de gemeenschappelijke code bevat van Bullet en Enemy.

Zie ook https://mosa.issaris.com/2020/prog2/slides/classes2.html

1.1.7 Opgave: Entity class

Introduceer een class Entity gelijkaardig aan de class Bullet.

 1
 2class Entity:
 3    def __init__(self, x, y):
 4        self.x = x
 5        self.y = y
 6        # ...
 7
 8    def update(self):
 9        # ...
10
11    def blit(self, screen, img):
12        # ...
13
14
15class Bullet(Entity):
16    # ...
17
18
19class Enemy(Entity):
20    # ...