Pygame 4¶
In de vorige opgave werden reeds botsingen gedetecteerd tussen onze kogel en het vijandelijke ruimteschip. We speelden een geluid af als we raak geschoten hadden, maar helaas leek er iets niet te kloppen. Je geluid werd meermaals afgespeeld, en je zag ook meermaals ‘hit’ op het scherm verschijnen. Dit is omdat de kogel het ruimteschip raakte, maar zowel de kogel als de vijand verdwenen niet, waardoor de kogel het ruimteschip opnieuw bleef raken zolang ze elkaar overlapten.
Opgave 25¶
We passen in de code de gegevens die we bijhouden over het vijandelijk ruimteschip uit met het al dan niet in geraakt zijn van het vijandelijke ruimteschip. We gebruiken hiervoor een variabele van het type “bool”.
Hieronder vinden jullie de onvolledige code voor deze aanpassing. Bekijk de regels gemarkeerd met ‘nieuw’ aandachtig, en pas ze aan zodat een kogel de vijand slechts eenmaal raakt.
import random
import pygame
from pygame import Rect
WIDTH = 800
HEIGHT = 600
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
# Start de klok
clock = pygame.time.Clock()
sound = pygame.mixer.Sound("bow.wav")
explosion = pygame.mixer.Sound("explosion.wav")
player = pygame.image.load("ship.png")
bullet = pygame.image.load("bullet.png")
enemy = pygame.image.load("enemyship.png")
# Positie van de speler, en verplaatsing van de speler
x = WIDTH / 2
y = HEIGHT - 110
xchange = 0
ychange = 0
# Positie van de kogel, en verplaatsing van de kogel
bullet_x = 0
bullet_y = 0
bullet_x_change = 0
bullet_y_change = 0
# Positie van de vijand, en verplaatsing van de vijand
enemy_alive = # nieuw: leeft de vijand nog?
enemy_x = WIDTH - 200
enemy_y = 0
enemy_x_change = 0
enemy_y_change = 1
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
sound.play()
bullet_x = x
bullet_y = y
bullet_y_change = -5
elif event.key == pygame.K_LEFT:
xchange = -1.5
elif event.key == pygame.K_RIGHT:
xchange = 1.5
elif event.key == pygame.K_UP:
ychange = -1.5
elif event.key == pygame.K_DOWN:
ychange = 1.5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
xchange = 0
elif event.key == pygame.K_RIGHT:
xchange = 0
if event.key == pygame.K_UP:
ychange = 0
elif event.key == pygame.K_DOWN:
ychange = 0
# Verplaats de speler
x += xchange
y += ychange
# Verplaats de kogel
bullet_y += bullet_y_change
if enemy_alive: # nieuw: Als de vijand nog leeft, doe dan het volgende
# Verplaats de vijand
enemy_x += enemy_x_change
enemy_y += enemy_y_change
# Als de vijand buiten het scherm gaat,
# plaats hem dan terug bovenaan het scherm
if enemy_y > HEIGHT:
enemy_y = 0
enemy_x = random.randint(0, WIDTH)
# Kijk of er een botsing is
enemy_rect = Rect(enemy_x, enemy_y, 32, 32)
bullet_rect = Rect(bullet_x, bullet_y, 8, 8)
if enemy_rect.colliderect(bullet_rect):
explosion.play()
print("hit")
enemy_alive = # nieuw: Wat is de nieuwe status van de vijand?
# Teken de speler, de vijand en de kogel
screen.fill("white")
screen.blit(player, (x, y))
screen.blit(enemy, (enemy_x, enemy_y))
screen.blit(bullet, (bullet_x, bullet_y))
pygame.display.flip()
# Wacht zodanig dat we maximal 60 FPS halen
clock.tick(60)
Link naar opgave25.py
Opgave 26¶
Hoewel we in de vorige opdracht het ruimteschip raakten, veranderde er visueel niets aan het ruimteschip.
Pas de code in opgave 25 aan zodat je na het raken van een vijandelijk ruimteschip, de nieuwe afbeelding gebruikt bij het tekenen van het vijandelijk ruimteschip.
Dit doe je door:
De nieuwe afbeelding in te laden net zoals je de kogel, je eigen ruimteschip, en het vijandelijk ruimteschip nu al inlaadt.
Bij het raken van het ruimteschip, de afbeelding ‘enemy’ te vervangen door ‘enemy_slain’.
Meerdere kogels¶
Je hebt vast gemerkt dat hoeveel je ook schiet, je slechts 1 kogel op het scherm kan doen verschijnen. De vorige kogel lijkt te verdwijnen zodra je een tweede maal schiet. De reden hiervoor is dat we ook slechts informatie over 1 kogel bijhouden in ons spel:
# Positie van de kogel, en verplaatsing van de kogel
bullet_x = 0
bullet_y = 0
bullet_x_change = 0
bullet_y_change = 0
Je zou een tweede kogel kunnen toevoegen, door nieuwe variabelen te introduceren:
# Positie van kogel 2, en verplaatsing van kogel 2
bullet2_x = 0
bullet2_y = 0
bullet2_x_change = 0
bullet2_y_change = 0
Maar, dit zou snel problematisch worden als je vele kogels zou willen afvuren.
Merk trouwens op, dat we eigenlijk niet alle gegevens per kogel hoeven bij te houden. We kunnen veronderstellen dat iedere kogel even snel vliegt, en dan per kogel enkel een nieuw paar x- en y-coördinaten bijhouden:
# Positie van de kogel, en verplaatsing van de kogel
bullet_x_change = 0
bullet_y_change = 0
bullet1_x = 0
bullet1_y = 0
bullet2_x = 0
bullet2_y = 0
Hoewel dit de code een beetje eenvoudiger maakt, is ook deze code niet praktisch bruikbaar als je veel kogels wil kunnen afschieten.
Wat we zouden willen doen, is zoveel kogels afschieten als we willen, en het programma de posities van alle kogels laten bijhouden. Dit kunnen we doen door gebruik te maken van een lijst:
# Positie van de kogel, en verplaatsing van de kogel
bullet_x_change = 0
bullet_y_change = 0
# Een Python lijst waarin we de coördinaten van kogels bijhouden
bullets = [
0, 0, # bullet1_x, bullet1_y
0, 0, # bullet2_x, bullet2_y
]