Стрелялка с Pygame №8: звук и музыка

Восьмая часть проекта «Стрелялка с Pygame». Если пропустили, обязательно вернитесь и начните с первой части.
В этом уроке в игре появятся музыка и звуки.

В этой серии уроков будет создана полноценная игра на языке Python с помощью библиотеки Pygame. Она будет особенно интересна начинающим программистам, которые уже знакомы с основами языка и хотят углубить знания, а также узнать, что лежит в основе создания игр.

Сила звука

Хороший звук (музыка и звуковые эффекты) — это один из самых эффективных способов добавить в игру «энергии». Это неофициальный термин из геймдизайна, который применяется по отношению к элементам, делающим игры более веселыми и захватывающими. Его часто называют «чувством игры» (game feel).

Как и в случае с графикой, найти подходящие звуки может быть непросто. OpenGameArt — отличное место для поиска аудио-ассетов, но в этот раз попробуем другой подход — создать звуковые эффекты самостоятельно.

Создание собственных звуков

Для этого будет использоваться инструмент под названием Bfxr. Он выглядит следующим образом:

Создание собственных звуков

Но не стоит пугаться этого многообразия слайдеров и жаргонизмов. Кнопки слева случайным образом генерируют звук выбранного типа. Попробуйте нажать «Shoot» несколько раз. Сгенерированные звуки сохранятся в списке ниже.

Для Стрелялки нужны звуки «выстрела» и «взрыва». После получения подходящего звука, нужно нажать на кнопку «Export Wav» (НЕ «Save to Disk»).

Дальше необходимо создать папку «snd» (как и для изображений) и переместить WAV-файлы туда. Можете использовать, например, эти звуки:

Обратите внимание, что здесь два звука взрыва. Можно сделать так, чтобы они воспроизводились случайным образом, и таким образом добавить разнообразия в игру.

Теперь нужна музыка. Ее можно поискать на OpenGameArt или использовать следующую:

Обратите внимание, что автор указал «Attribution Instructions» (модель атрибуции). Это условия, которые выбрал музыкант, чтобы лицензировать свое произведение. Это значит, что его нужно упомянуть. Для этого достаточно скопировать и вставить текст со страницы в верхнюю часть программы.

Добавление звука в игру

Теперь можно добавлять звуки в игру. Во-первых, нужно указать, в какой папке они находятся:

# Frozen Jam by tgfcoder <https://twitter.com/tgfcoder> licensed under CC-BY-3
# Art from Kenney.nl
import pygame
import random
from os import path

img_dir = path.join(path.dirname(__file__), 'img')
snd_dir = path.join(path.dirname(__file__), 'snd')

Дальше файлы необходимо загрузить. Это стоит сделать в том же месте, где загружалась графика. Сначала звук выстрелов:

# Загрузка мелодий игры
shoot_sound = pygame.mixer.Sound(path.join(snd_dir, 'pew.wav'))

Теперь, когда звук загружен и присвоен переменной shoot_sound, на него можно ссылаться. Важно, чтобы он воспроизводился каждый раз, когда игрок стреляет, поэтому его нужно добавить в метод shoot():

    def shoot(self):
        bullet = Bullet(self.rect.centerx, self.rect.top)
        all_sprites.add(bullet)
        bullets.add(bullet)
        shoot_sound.play()

Это все, что требуется. Стрелять теперь будет приятнее!

Дальше нужны звуки взрывов. Загрузим оба и добавим их в список:

# Загрузка мелодий игры
shoot_sound = pygame.mixer.Sound(path.join(snd_dir, 'pew.wav'))
expl_sounds = []
for snd in ['expl3.wav', 'expl6.wav']:
    expl_sounds.append(pygame.mixer.Sound(path.join(snd_dir, snd)))

Для воспроизведения взрывов нужно будет случайным образом выбирать один и включать его при разрушении астероида.

    # проверка, попала ли пуля в моб
    hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
    for hit in hits:
        score += 50 - hit.radius
        random.choice(expl_sounds).play()
        m = Mob()
        all_sprites.add(m)
        mobs.add(m)

Музыка

Наконец, необходимо добавить фоновую музыку, которая сделает игру более эмоциональной. Здесь необходим другой подход, потому что музыка играет непрерывно.

Сначала загружаем файл:

expl_sounds = []
for snd in ['expl3.wav', 'expl6.wav']:
    expl_sounds.append(pygame.mixer.Sound(path.join(snd_dir, snd)))
pygame.mixer.music.load(path.join(snd_dir, 'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
pygame.mixer.music.set_volume(0.4)

Музыка довольно громкая, поэтому, чтобы она не перекрывала звуки, необходимо опустить ее максимальную громкость до 40%.

Чтобы музыка играла, нужно просто выбрать в каком месте кода она будет стартовать. В случае Стрелялки это будет позиция перед началом игрового цикла.

score = 0
pygame.mixer.music.play(loops=-1)
# Цикл игры
running = True

Параметр loops определяет, как часто трек будет повторяться. Если установить значение на -1, то он будет воспроизводиться бесконечно.

Игра теперь ощущается совсем по-другому. Геймплей не поменялся, но с музыкой и звуками все воспринимается живее. Осталось поэкспериментировать с разными звуками и понять, какие подходят лучше.

Код урока — shmup-8.py

В следующем уроке добавим игроку щиты, чтобы он не умирал так быстро.