Класс Sound и модуль pygame.mixer.music
В Pygame для работы с аудио предназначены модули pygame.mixer и pygame.mixer.music. Модули похожи, однако pygame.mixer в первую очередь адаптирован для добавления и настройки звуковых эффектов в игре. В то время как pygame.mixer.music – для добавления фоновой музыки.
Функция pygame.mixer.music.load() загружает потоковое аудио, т. е. не грузит файл целиком, а делает это отдельными порциями. В результате можно проигрывать только один файл за раз. Однако можно ставить файлы в очередь функцией queue(). Поддерживает в том числе формат mp3 (но не в Ubuntu).
С другой стороны, в pygame.mixer ключевым является класс Sound. Он позволяет загружать, проигрывать и выполнять ряд других действий с файлами форматов wav или ogg. При создании экземпляра Sound в конструктор передается имя файла.
В примере ниже подгружается фоновая музыка: pygame.mixer.music.load(). Функция не возвращает никакого "музыкального" объекта, поэтому результат ее вызова не присваивается переменной.
С помощью функции music.play() файл начинает проигрываться. Если требуется зациклить композицию, то в play() передается число -1. Положительный аргумент указывает на количество повторов + одно дополнительное. То есть, если надо проиграть композицию 2 раза, то в функцию передается число 1.
В программе при нажатии на клавишу 1 клавиатуры музыка ставится на паузу: music.pause(). Клавиша 2 уменьшает громкость в два раза: music.set_volum(0.5). Нажатие 3 возвращает громкость на прежний уровень. Функция unpause() вызывается на случай, если до этого музыка была выключена (клавишей 1).
В примере создаются два объекта типа Sound. У них есть свой метод play(). В данном случае файлы проигрываются при клике левой и правой кнопками мыши. Объекты Sound могут проигрываться одновременно, так как обычно принадлежат разным каналам. Если требуется более тонкое управление звуками, дополнительно используют класс Channel.
Программа ниже в процессе выполнения интерпретатором python3.6 может выбросить ошибку, в 3.8 – все нормально. На официальном сайте pygame.org рекомендуется использовать Pygame с версией Питона от 3.7.7.
import pygame as pg import sys pg.init() sc = pg.display.set_mode((400, 300)) pg.mixer.music.load('Beethoven.ogg') pg.mixer.music.play() sound1 = pg.mixer.Sound('boom.wav') sound2 = pg.mixer.Sound('one.ogg') while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() elif i.type == pg.KEYUP: if i.key == pg.K_1: pg.mixer.music.pause() # pygame.mixer.music.stop() elif i.key == pg.K_2: pg.mixer.music.unpause() # pygame.mixer.music.play() pg.mixer.music.set_volume(0.5) elif i.key == pg.K_3: pg.mixer.music.unpause() # pygame.mixer.music.play() pg.mixer.music.set_volume(1) elif i.type == pg.MOUSEBUTTONUP: if i.button == 1: sound1.play() elif i.button == 3: sound2.play() pg.time.delay(20)
Если закомментировать вызовы функций pause() и unpause() и раскомментировать stop() и play(), то результат будет схож. Разница в том, что при использовании комбинации stop-play файл начнет проигрываться сначала, а при pause-unpause продолжится с места останова.
Если у вас нет файлов wav или ogg для тестов, можете найти немного в каталоге data модуля pygame.examples. Модуль находится в папке библиотеки pygame, адрес которой можно посмотреть так:
>>> import pygame >>> pygame.__file__ '/home/.../pygame/__init__.py'
Практическая работа
Добавьте фоновую музыку и звук столкновения в игру из практической работы предыдущего урока.
Окно игры должно закрываться только после того, как звук столкновения полностью проиграется. В зависимости от решения вам может понадобиться метод get_length() объекта типа Sound. Метод возвращает продолжительность звука, выраженную в секундах (тип float).
Курс с примерами решений практических работ:
pdf-версия, android-приложение