Расписал обзор процесса добавления звуков в игру :) Звуки!
Я наконец-то заканчиваю первую итерацию звуковых эффектов Земерота.
Не особо разбираюсь в звуках и это моя первая личная поделка, в которой я пытаюсь организовать чего-то сложнее "пиу-пиу", так что прям свои звуки записывать не решился. Все взято с:
* opengameart.org - тут брал целые паки ("RPG Sound Pack", "Owlish Media Sound Effects", и т.п.) и подбирал из них релевантное.
* freesound.org - а тут выколупывал уже отдельные штучные записи.
Для всего скачанного сохранял ссылки и следил за лицензиями (CC0 или CC BY) - что бы с чистой совестью указать авторов в ридми и сходить по каждой ссылке поблагодарить их.
Пришлось даже освоить какие-то азы работы в Audacity для базового редактирования (в основном по ютуб видяхам, а текстом про изменения звуков совсем тяжко воспринимается):
* вырезание интересующих кусков из длинных записей (например, звуки оседающей пыли, толкания по поверхности и человеческой ходьбы все вырезаны из одной минутной записи, где человек упорно юлозит камнем по песку);
* создание своих эффектов на основе комбинаций кусков исходников (например, брызги крови - поставленная вплотную с наложением серия легких ударов по какому-то фрукту);
* удаление очень заметных фоновых шумов или лишних частот;
* перевод всего в 44100Hz и хотя бы грубо подгон всех отобранных звуков друг к другу по громкости.
Порядочно вечеров провел, слушая всю эту получившуюся разношерстную аудиобиблиотеку, и пытаясь наскрести чего-то цельное. В итоге, игра обзавелась звуками:
* кельтских барабанов - в качестве минималистичной фоновой музыки;
* UI: нажатия на кнопки и началом хода;
* шагов, кряхтенья и вскриков (разными для людей и демонов);
* оседающей пыли и протаскивания по земле;
* сломанной брони, ударов по мясу и брызг крови;
* взмахами для острого и тупого оружия;
* взрывом бомб, горения, ожогов, отравления;
* магии, лечения и кровожадности;
Теперь про код. Поскольку игра недавно переехала на Федин macroquad, логично использовать квадовый звук: quad_snd. Базовый API простой, вот пример с парочкой звуков:
// создаем миксер
let mut mixer = SoundMixer::new();
// загружаем wav или ogg звук из байт
let sound_wav: Sound = decoder::read_wav(BYTES_WAV)?;
let sound_ogg: Sound = decoder::read_ogg(BYTES_OGG)?;
// отправляем звуки на однократное параллельное проигрывание
mixer.play(sound_wav);
mixer.play(sound_ogg);
// каждый кадр дергаем миксер в главном цикле
loop {
// ...
mixer.frame();
// ...
}
.play возвращает SoundId, используя который можно потом останавливать звук, менять его громкость и т.п.
Работает quad_snd на Linux/Win/macOS/WASM'е, но библиотека пока довольно сырая, доступная только напрямую с гитхаба - надо быть готовым к багрепортам, что у кого-то на машине звук не завелся.
Интеграция в код Земерота довольно прямолинейная:
* Завел глобальный ленивый миксер, используя once_cell::Lazy, и добавил его дергание каждый кадр.
* Изначальную асинхронную загрузку звуков пихнул в стандартный assets.rs модуль.
* Непосредственно запуск звуков на проигрывание выглядит как `play_sound(&assets::get().sound.step)` и вставляется в нужные места визуализаторов событий между всякими действиями, добавляющими, перекрашивающими и передвигающими спрайты. Внутри эта функция создает замыкание для scene::action::Custom, где дергается mixer::play(sound).
* Ну и добавил в компонент `Agent` поле типа `enum AgentKind { Human, Imp }`, что бы выбирать какие звуки играть.
В assets/sound директорию репозитория идут только 44100Hz (quad_snd не поддерживает другие рейты) .ogg файлы. Решил не заморачиваться с сохранением wav исходников и проектов Audacity ни в каком репозитории - если что понадобится существенно изменить в аудиофайлах, думаю, по ссылкам на исходники перевыкачаю архивы с исходниками и повторю операции.
Демо: