Weitere Wellen
Teil des Abschnitts Sprites und Bilder der Pygame-Journey von Coddy. Lektion 38 von 39.
Eine Welle ist noch kein richtiges Spiel. Beschreibe die Wellen als Daten, ein Tupel pro Welle: ihr Bild, wie viele Gegner es gibt und ihre Geschwindigkeit.
WAVES = [(red_image, 4, 1), (green_image, 5, 2)]wave ist der Index der gerade gespielten Welle. Starte die erste mit image, count, speed = WAVES[wave]; dadurch wird das Tupel in drei Namen entpackt. Rufe danach spawn_wave(image, count, speed) auf. Wenn enemies leer ist, ist die Welle geschafft:
if not enemies:
wave += 1
if wave < len(WAVES):
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)Eine leere Gruppe zählt als falsch, also ist not enemies wahr, sobald der letzte Gegner verschwunden ist. Eine neue Welle ist ein weiteres Tupel in der Liste.
Aufgabe
MittelLass die Wellen eine nach der anderen erscheinen.
- Lade
enemy_green.pngundenemy_yellow.pngund erstelleWAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]. - Setze
wave = 0und lasse die erste Welle ausWAVES[wave]erscheinen. - Wenn
enemiesleer ist, gehe zur nächsten Welle und lasse sie erscheinen, falls es eine gibt. - Zeichne, solange
wave < len(WAVES)gilt,f"Wave {wave + 1}"mit der oberen Mitte bei(320, 10).
Drücke „Spielen“ und besiege eine Welle: Wave 2 bringt 8 grüne Gegner. Drücke dann „Prüfen“.
Probier es selbst
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Star Patrol")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()
red_image = pygame.image.load("assets/images/enemy_red.png").convert_alpha()
explosion_frames = []
for number in range(1, 5):
explosion_frames.append(pygame.image.load(f"assets/images/explosion_{number}.png").convert_alpha())
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(midbottom=(320, 470))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 6
if keys[pygame.K_RIGHT]:
self.rect.x += 6
self.rect.clamp_ip(screen.get_rect())
class Laser(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = laser_image
self.rect = self.image.get_rect(midbottom=(x, y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
self.rect.y -= 10
if self.rect.bottom < 0:
self.kill()
class Enemy(pygame.sprite.Sprite):
def __init__(self, image, x, y, speed):
super().__init__()
self.image = image
self.rect = self.image.get_rect(center=(x, y))
self.mask = pygame.mask.from_surface(self.image)
self.speed = speed
def update(self):
self.rect.y += self.speed
class Explosion(pygame.sprite.Sprite):
def __init__(self, center):
super().__init__()
self.index = 0
self.timer = 0
self.image = explosion_frames[0]
self.rect = self.image.get_rect(center=center)
def update(self):
self.timer += 1
if self.timer == 5:
self.timer = 0
self.index += 1
if self.index == len(explosion_frames):
self.kill()
else:
self.image = explosion_frames[self.index]
def spawn_wave(image, count, speed):
for i in range(count):
x = random.randint(40, 600)
enemies.add(Enemy(image, x, -40 - i * 120, speed))
player = Player()
lasers = pygame.sprite.Group()
enemies = pygame.sprite.Group()
explosions = pygame.sprite.Group()
last_shot = 0
score = 0
lives = 3
spawn_wave(red_image, 6, 2)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if lives > 0:
player.update()
keys = pygame.key.get_pressed()
now = pygame.time.get_ticks()
if keys[pygame.K_SPACE] and now - last_shot >= 250:
lasers.add(Laser(player.rect.centerx, player.rect.top))
last_shot = now
lasers.update()
enemies.update()
for enemy in enemies:
if enemy.rect.top > 480:
enemy.kill()
lives -= 1
hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
score += 10
explosions.add(Explosion(enemy.rect.center))
crashes = pygame.sprite.spritecollide(player, enemies, True, pygame.sprite.collide_mask)
for enemy in crashes:
lives -= 1
explosions.add(Explosion(enemy.rect.center))
explosions.update()
screen.fill((12, 14, 30))
enemies.draw(screen)
lasers.draw(screen)
screen.blit(player.image, player.rect)
explosions.draw(screen)
score_text = font.render(f"Score: {score}", True, (240, 240, 240))
screen.blit(score_text, (10, 10))
lives_text = font.render(f"Lives: {max(lives, 0)}", True, (240, 240, 240))
screen.blit(lives_text, lives_text.get_rect(topright=(630, 10)))
if lives <= 0:
message = font.render("Game over", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(320, 240)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Alle Lektionen in Sprites und Bilder
1Bilder laden
Ein Bild ladenMit einem Rect platzierenDas Bild bewegenEinen Hintergrund kachelnTransparente Pixel2Drehen, Spiegeln, Skalieren
Um den Mittelpunkt drehenIn Flugrichtung ausrichtenEin Bild skalierenVom Original aus drehen3Klassen für Spielobjekte
Deine erste KlasseMethodenSelf ist das ObjektEine Liste von ObjektenObjekte mit BildernEine Liste von GegnernEine Unterklasse6Animation mit Sprite Sheets
Ein Sprite Sheet zuschneidenEin Frame-ZählerMit Zeit animierenEine einmalige ExplosionÜbe selbstständig: Pygame-Playground