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

5083

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

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

Сила звука

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

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

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

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

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

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

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

Python data course

Дальше необходимо создать папку «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

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

Тест на знание python

Что выведет этот код?
Какая функция удаляет объект из списка?
Как узнать длину списка?
Что выведет этот код?
Верно ли данное утверждение: "В Python есть два типа чисел: целые числа и числа с плавающей точкой"?