Menu
CoddyTech

Musik für jeden Zustand

Teil des Abschnitts Sound und Spielgefühl der Pygame-Journey von Coddy. Lektion 6 von 23.

Jeder Zustand eines Spiels kann seine eigene Musik haben: ein ruhiges Thema im Menü, einen flotten Titel, während du spielst, eine kurze Melodie, wenn du gewinnst oder verlierst. Um zu wechseln, lade den neuen Titel und spiele ihn ab. Beim Laden eines neuen Titels wird der alte gestoppt. Eine kleine Funktion fasst die beiden Zeilen zusammen:

def play_music(path, loops=-1):
    pygame.mixer.music.load(path)
    pygame.mixer.music.play(loops)

Wechsle die Musik in dem Moment, in dem sich der Zustand ändert, in der Zeile, die state festlegt:

if player.colliderect(goal):
    state = "win"
    play_music("assets/music/win.ogg", 0)

Diese Zeile wird einmal ausgeführt, also startet der Titel einmal. Wechsle die Musik nicht innerhalb von if state == "win": im Zeichenteil: Dieser wird bei jedem Frame ausgeführt und startet den Titel 60-mal pro Sekunde neu.

Die Sieg- und Niederlagemelodien sind kurz und enden von selbst, deshalb wird für loops der Wert 0 verwendet. Das Thema und der Leveltitel laufen mit -1 in einer Schleife.

challenge icon

Aufgabe

Mittel

Mit der Eingabetaste startet das Spiel; das blaue Quadrat gewinnt am grünen Ziel und verliert in der Lava. Weise jedem Zustand seine Musik zu:

  1. Schreibe play_music(path, loops=-1), das einen Titel lädt und abspielt.
  2. Spiele vor der Schleife assets/music/theme.ogg ab.
  3. Wenn der Zustand zu "play" wechselt, spiele assets/music/level.ogg ab.
  4. Wenn er zu "win" wechselt, spiele assets/music/win.ogg einmal ab (loops 0); bei "lose" spiele assets/music/lose.ogg einmal ab.
  5. Wenn die Eingabetaste zurück zu "menu" führt, spiele theme.ogg erneut ab.

Probier es selbst

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Lava Run")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)

player = pygame.Rect(40, 160, 30, 30)
goal = pygame.Rect(420, 160, 30, 30)
lava = pygame.Rect(0, 320, 480, 40)
state = "menu"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
            if state == "menu":
                state = "play"
                player.topleft = (40, 160)
            elif state in ("win", "lose"):
                state = "menu"

    if state == "play":
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            player.x -= 4
        if keys[pygame.K_RIGHT]:
            player.x += 4
        if keys[pygame.K_UP]:
            player.y -= 4
        if keys[pygame.K_DOWN]:
            player.y += 4
        player.clamp_ip(screen.get_rect())
        if player.colliderect(goal):
            state = "win"
        elif player.colliderect(lava):
            state = "lose"

    screen.fill((30, 30, 46))
    if state == "menu":
        title = font.render("Press Enter to start", True, (240, 240, 240))
        screen.blit(title, title.get_rect(center=(240, 180)))
    else:
        pygame.draw.rect(screen, (230, 90, 40), lava)
        pygame.draw.rect(screen, (90, 200, 120), goal)
        pygame.draw.rect(screen, (80, 160, 255), player)
        if state == "win":
            message = font.render("You win!", True, (240, 240, 240))
            screen.blit(message, message.get_rect(center=(240, 100)))
        elif state == "lose":
            message = font.render("Game over", True, (240, 240, 240))
            screen.blit(message, message.get_rect(center=(240, 100)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Alle Lektionen in Sound und Spielgefühl

Übe selbstständig: Pygame-Playground