Menu
CoddyTech

Wellen und Sieg

Teil des Abschnitts Sprites und Bilder der Pygame-Journey von Coddy. Lektion 36 von 36.

Der letzte Baustein: mehr Wellen, jede schwieriger, und eine Möglichkeit zu gewinnen. Beschreibe die Wellen als Daten, ein Tupel pro Welle: ihr Bild, wie viele Gegner es gibt und ihre Geschwindigkeit.

WAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]

wave ist der Index der gerade gespielten Welle. Starte die erste mit image, count, speed = WAVES[wave], wodurch das Tupel in drei Namen entpackt wird, und dann mit spawn_wave(image, count, speed). 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)

Sobald wave len(WAVES) erreicht, sind alle Wellen geschafft: Der Spieler gewinnt. Beende dann ebenfalls das Spiel mit if lives > 0 and wave < len(WAVES): und zeige You win! an. Eine vierte Welle ist ein weiteres Tupel in der Liste.

challenge icon

Aufgabe

Mittel
  1. Lade enemy_green.png und enemy_yellow.png und erstelle die obige Liste WAVES.
  2. Setze wave = 0 und starte die erste Welle aus WAVES.
  3. Wenn enemies leer ist, gehe zur nächsten Welle über und starte sie, falls es eine gibt.
  4. Aktualisiere nur, solange lives > 0 and wave < len(WAVES) gilt.
  5. Zeige während des Spiels Wave und wave + 1 mit der oberen Mitte bei (320, 10) an. Zeige nach der letzten Welle You win! mittig bei (320, 240) an, sofern das Spiel nicht vorbei ist.

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()
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Sprites und Bilder

Übe selbstständig: Pygame-Playground