Menu
CoddyTech

Музыка для каждого состояния

Часть раздела Звук и игровые ощущения путешествия по Pygame на Coddy. Урок 6 из 23.

У каждого состояния игры может быть своя музыка: спокойная мелодия в меню, энергичный трек во время игры, короткая мелодия при победе или поражении. Чтобы переключиться, загрузите новый трек и запустите его. Загрузка нового трека останавливает предыдущий. Небольшая функция объединяет эти две строки:

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

Переключайте музыку в момент смены состояния, в строке, где задаётся state:

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

Эта строка выполняется один раз, поэтому трек запускается один раз. Не переключайте музыку внутри if state == "win": в части отрисовки: она выполняется на каждом кадре и перезапускает трек 60 раз в секунду.

Мелодии победы и поражения короткие и заканчиваются сами, поэтому для них значение loops равно 0. Главная тема и трек уровня зацикливаются со значением -1.

challenge icon

Задание

Средне

Нажми Enter, чтобы начать игру; синий квадрат побеждает у зелёной цели и проигрывает в лаве. Назначь каждому состоянию свою музыку:

  1. Напиши play_music(path, loops=-1), которая загружает и воспроизводит композицию.
  2. Перед циклом воспроизведи assets/music/theme.ogg.
  3. Там, где состояние становится "play", воспроизведи assets/music/level.ogg.
  4. Там, где состояние становится "win", один раз воспроизведи assets/music/win.ogg (loops 0); для "lose" один раз воспроизведи assets/music/lose.ogg.
  5. Там, где Enter возвращает состояние к "menu", снова воспроизведи theme.ogg.

Попробуйте сами

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()

Все уроки раздела Звук и игровые ощущения

Потренируйтесь самостоятельно: Песочница Pygame