Funken bei jedem Treffer
Teil des Abschnitts Sound und Spielgefühl der Pygame-Journey von Coddy. Lektion 21 von 23.
Ein Gegner, der explodiert, sollte sich auch so anfühlen. Beginne mit Funken: eine Partikelexplosion dort, wo der Gegner war.
Explosionen treten an zwei Stellen auf: bei einem Lasertreffer und bei einem Zusammenstoß. Deshalb kommt die Explosion in eine Funktion:
def burst(center):
for i in range(16):
particles.append({"x": center[0], "y": center[1],
"vx": random.uniform(-4, 4), "vy": random.uniform(-4, 4),
"life": random.randint(15, 30)})Die Funktion erzeugt nur die Funken. Sie zu bewegen ist Aufgabe jedes Frames, wie im Kapitel Partikel: Bewege jeden einzelnen, verringere seine Lebensdauer und behalte nur die, die noch leben.
Füge das neben explosions.update() ein, außerhalb von if lives > 0 .... Auch der Zusammenstoß, der das Spiel beendet, erzeugt eine Explosion, und die Funken sollten nach Game over noch weiterfliegen. Zeichne die Funken nach den Explosionen, damit sie im Vordergrund liegen.
Aufgabe
Mittel- Erstelle vor der Schleife
particles = []. - Schreibe
burst(center): 16 Partikel beicenter,vxundvyausrandom.uniform(-4, 4),lifeausrandom.randint(15, 30). - Rufe
burst(enemy.rect.center)dort auf, wo ein Laser einen Gegner zerstört und wo ein Gegner mit dem Schiff zusammenstößt. - Bewege neben
explosions.update()die Partikel, verringere ihre Lebensdauer und entferne die erloschenen. - Zeichne nach den Explosionen jedes Partikel als orangefarbenen Kreis
(255, 170, 60)mit dem Radiuslife // 10 + 1.
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()
green_image = pygame.image.load("assets/images/enemy_green.png").convert_alpha()
yellow_image = pygame.image.load("assets/images/enemy_yellow.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())
laser_sound = pygame.mixer.Sound("assets/sounds/laser.ogg")
laser_sound.set_volume(0.4)
explosion_sound = pygame.mixer.Sound("assets/sounds/explosion.ogg")
hit_sound = pygame.mixer.Sound("assets/sounds/hit.ogg")
WAVES = [(red_image, 6, 2), (green_image, 8, 2), (yellow_image, 10, 3)]
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 play_music(path, loops=-1):
pygame.mixer.music.load(path)
pygame.mixer.music.play(loops)
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
wave = 0
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)
pygame.mixer.music.set_volume(0.5)
play_music("assets/music/level.ogg")
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if lives > 0 and wave < len(WAVES):
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
laser_sound.play()
lasers.update()
enemies.update()
for enemy in enemies:
if enemy.rect.top > 480:
enemy.kill()
lives -= 1
hit_sound.play()
hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
score += 10
explosion_sound.play()
explosions.add(Explosion(enemy.rect.center))
crashes = pygame.sprite.spritecollide(player, enemies, True, pygame.sprite.collide_mask)
for enemy in crashes:
lives -= 1
hit_sound.play()
explosions.add(Explosion(enemy.rect.center))
if not enemies:
wave += 1
if wave < len(WAVES):
image, count, speed = WAVES[wave]
spawn_wave(image, count, speed)
else:
play_music("assets/music/win.ogg", 0)
if lives <= 0:
play_music("assets/music/lose.ogg", 0)
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 wave < len(WAVES):
wave_text = font.render(f"Wave {wave + 1}", True, (240, 240, 240))
screen.blit(wave_text, wave_text.get_rect(midtop=(320, 10)))
if lives <= 0:
message = font.render("Game over", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(320, 240)))
elif wave == len(WAVES):
message = font.render("You win!", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(320, 240)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Sound und Spielgefühl
6Star Patrol aufpolieren
Star-Patrol-SoundsFunken bei jedem TrefferÜbe selbstständig: Pygame-Playground