Звук и музыка

Без звука даже отличная игра кажется неживой. Pygame проигрывает короткие эффекты и фоновую музыку буквально в несколько строк.
Суть: короткие эффекты грузят как pygame.mixer.Sound и проигрывают методом play, а длинную фоновую музыку — через pygame.mixer.music, который стримит файл с диска.

Звук добавляет игре половину её жизни. Прыжок, выстрел, взрыв, подбор монетки — каждый эффект делает действие ощутимым. В Pygame за звук отвечает модуль mixer, и он различает два типа аудио: короткие эффекты и длинную музыку. Разница в том, как они хранятся в памяти.

Короткие звуки (Sound) загружаются в память целиком. Это быстро и позволяет проигрывать их мгновенно и одновременно по нескольку штук — представь десяток выстрелов подряд. Грузишь один раз: sound = pygame.mixer.Sound("shoot.wav"), проигрываешь: sound.play(). Лучший формат — WAV или OGG.

Фоновая музыка — это длинный трек, который грузить в память целиком расточительно. Поэтому pygame.mixer.music стримит её прямо с диска, по кусочкам. Загрузил: pygame.mixer.music.load("theme.ogg"), запустил по кругу: play(-1). В каждый момент играет только одна музыка, зато эффектов поверх — сколько угодно.

Как работает под капотом

Sound держит весь звук в RAM и может играть много копий разом через каналы микшера. music читает файл потоком, экономя память:

   КОРОТКИЙ ЭФФЕКТ (Sound)     ФОНОВАЯ МУЗЫКА (music)

   файл -> вся в память        файл на диске
           |                        |  стрим кусками
        play() -> канал 1           v
        play() -> канал 2     один поток воспроизведения
        play() -> канал 3     play(-1) = по кругу
   (много одновременно)       (только один трек)

В pygame (читаем):

pygame.mixer.init()

shoot = pygame.mixer.Sound("shoot.wav")   # эффект в память
shoot.set_volume(0.5)

pygame.mixer.music.load("theme.ogg")      # музыка стримом
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play(-1)               # зациклить

# при выстреле:
shoot.play()

Логику «когда можно проиграть звук» (например, кулдаун, чтобы эффект не трещал каждый кадр) проверим без аудио. Попробуй сам:

COOLDOWN = 0.2    # минимум секунд между выстрелами
last_shot = -999.0

def can_play(now):
    global last_shot
    if now - last_shot >= COOLDOWN:
        last_shot = now
        return True
    return False

for t in [0.0, 0.1, 0.25, 0.30, 0.55]:
    print(f"t={t:.2f}s -> играем звук? {can_play(t)}")

Каналы микшера и приоритеты

Внутри mixer звуки играют через каналы — это как дорожки в звуковом пульте. По умолчанию их около восьми, и каждый одновременный звук занимает свой канал. Если каналов не хватает (например, разом взорвалось двадцать врагов), новые звуки могут не проиграться или прервать старые. Число каналов задаётся через pygame.mixer.set_num_channels, а для важных звуков можно зарезервировать канал, чтобы их никогда не «затёрло» менее важными.

Полезно и понимать формат файлов. WAV — несжатый, грузится мгновенно и идеален для коротких эффектов, но занимает много места. OGG — сжатый, чуть дороже в распаковке, зато компактный, и для фоновой музыки это лучший выбор. MP3 поддерживается не везде и его лучше избегать. Правильная связка — короткие WAV-эффекты в память и длинная OGG-музыка стримом — даёт и отзывчивый звук, и экономную игру. Звук кажется второстепенным, пока его нет; стоит добавить — и игра оживает вдвое.

Не забудь дать игроку контроль над звуком — это базовое уважение к нему. Сделай громкость музыки и эффектов настраиваемой и предусмотри полное отключение: кто-то играет в тишине или со своей музыкой. Громкости задаются методом set_volume от 0.0 до 1.0, и держать музыку заметно тише эффектов — хорошее правило по умолчанию, иначе важные звуки утонут в фоне. И помни про инициализацию: pygame.mixer.init() должен пройти до загрузки звуков, иначе они молча не заиграют. Звук — мощный, но недооценённый новичками слой: грамотные эффекты на каждое действие и ненавязчивая фоновая музыка повышают ощущение качества игры едва ли не сильнее, чем красивая графика.

Частые ошибки

  • Грузить Sound каждый кадр — память течёт, звук заикается. Грузи один раз.
  • Использовать Sound для длинной музыки — она целиком влезет в RAM и съест память.
  • Забыть mixer.init() — звук просто не заиграет.

Best practices

  • Эффекты — Sound (WAV/OGG), музыка — mixer.music (OGG).
  • Делай громкость музыки тише эффектов: 0.3 против 0.6.
  • Ставь кулдаун на частые звуки, чтобы они не сливались в треск.

Итог: короткие эффекты — Sound и play(), фоновая музыка — mixer.music со стримингом. Правильный выбор бережёт память и звучит чисто.

Проверьте себя
1. Чем mixer.Sound отличается от mixer.music?
AНичем
BSound держит звук в памяти для коротких эффектов, music стримит длинную музыку с диска
CSound только для музыки
Dmusic проигрывает картинки
2. Что означает play(-1) для фоновой музыки?
AПроиграть один раз
BПроиграть задом наперёд
CЗациклить — играть по кругу
DВыключить звук