GameMaker Studio 2. Урок 8. Звук

Это воскресенье, мои чуваки.
Всем привет. Сегодня поговорим с вами о том, как подключить звук к своей игре. Как обычно: немного теории, немного практики.
Покажу вам сайт, где большинство звуков можно взять бесплатно и как его настраивать.
Ну и небольшие бонусы, само собой.

Ссылки на предыдущие гайды:

Первый гайд - Знакомство.

Второй гайд - События отрисовки, коллизия, скрипты.

Третий гайд - Камера и разрешение экрана.

Четвертый гайд - Иерархия объектов. Глобальные переменные.

Пятый гайд - Структуры данных. Сетка комнаты и размещение объектов по сетке.

Шестой гайд - Алгоритмы поиска путей.

Седьмой гайд - Сохранения и их загрузка. Бонус в конце!

План:
- Создание звука
- Подключим звук к кнопкам
- Глобальная настройка звука
- Заставим человечков издавать звук
- Музыка
- Тест звука
- Немного бонусов

Тема сегодня небольшая, поэтому сразу перейдём к делу.

Создание звука.


Прежде, чем приступать к работе, нам нужно подготовить материал. Вы можете записать звук самостоятельно, либо использовать свой: найденный в интернете или записанный самостоятельно.
Я предлагаю скачать уже готовый набор звуков для меню по ссылке:
Ссылка

Как видно, там несколько форматов: OGG, WAV и MP3. Использовать мы можем все из них.
Сохраните архив, распакуйте в удобное место. Можете сразу скопировать путь до него. Дальше нам нужно создать звук и загрузить его. Для этого найдём папочку Sound и там создадим, собственно, Sound.

GameMaker Studio 2. Урок 8. Звук Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок, Игры, Стратегия, Обучение, Видео

Звук назовём sndButton.
Итак. Если сейчас мы нажмём на появившийся звук, то увидим небольшое меню настроек для нашего звука. Пока нам это не интересно. Чтобы загрузить звук, нужно нажать на три точки справа от названия звука.

GameMaker Studio 2. Урок 8. Звук Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок, Игры, Стратегия, Обучение, Видео

Там всё просто: указываем путь до нужного нам файла. У меня это "modern2.wav". Можете выбирать любой формат, пока это не столь важно. Стоит лишь отметить, что форматы отличаются не только весом, но и качеством звука и возможностью на него влиять внутри движка.

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

Обратите внимание: внизу указанного меню у вас есть вкладка Audio Group. Это ничто иное, как группа звуков. Её можно (и нужно) использовать в тех случаях, когда нам нужно уменьшить или увеличить только определённые звуки. Например, сделать три настройки звука: общий, музыка, игра. С-но, здесь будет три аудио группы: стандарт, музыка, игра.
Чтобы добавить свою аудио группу нужно в верхней части экрана найти вкладку Tools, там - Audio Groups.

GameMaker Studio 2. Урок 8. Звук Разработка, Gamedev, Программирование, Инди, Инди игра, Gamemaker Studio 2, Образование, Длиннопост, Урок, Игры, Стратегия, Обучение, Видео

Подключим звук к кнопкам.

Для удобства используем объект oMMenu, который сделаем родительским объектом для всех наших кнопок в меню, в т.ч. в настройках.
Не забудьте прописать event_inherited(); у дочерних объектов в тех событиях, которые нужно будет унаследовать.

Для начала, в Create объявим одну переменную:

collided = false;
Она позволит нам проигрывать звук при наведении только один раз.

Теперь в Step'e сделаем простую конструкцию: если наведены на текущий объект и раньше его не касались, то проигрываем звук и говорим, что мы его коснулись.
var dmxg = device_mouse_x_to_gui(0);
var dmyg = device_mouse_y_to_gui(0);
if instance_position(dmxg, dmyg, self) != noone
{
if !collided
{
audio_play_sound(sndButton, 10, false);
collided = true;
}
}
else
{
collided = false;
}
Вот так просто мы сделали следующее:

Соответственно, чтобы проиграть звук нам была нужна команда:
audio_play_sound(Звук, Приоритет,  Зациклить)

Приоритет - то, в каком порядке звук обрабатывается. Значения либо от 0 до 100, либо от 0 до 1. Чем больше число - тем выше приоритет.

Глобальная настройка звука.

Раз есть звук - значит его можно настроить.
Для этого в комнате настроек создадим ещё одну кнопку: oSSound.
Как ни странно, но с помощью этой кнопки мы будем устанавливать значение громкости для всех звуков, в т.ч. музыки.

Для этого нужно в событии step будет прописать следующий код:

var dmxg = device_mouse_x_to_gui(0)
var dmyg = device_mouse_y_to_gui(0)
var sound = audio_get_master_gain(0);
if instance_position(dmxg, dmyg, self) != noone
{
if mouse_check_button_pressed(mb_left)
or mouse_check_button(mb_right)
{
if dmxg > x + 260
{
if sound < 1
{
sound += 0.01;
}
}
else if dmxg < x + 60
{
if sound > 0
{
sound -= 0.01;
}
}
audio_master_gain(sound) // Устанавливаем глобальный звук.
}
}
audio_master_gain(x) принимает на вход значение от 0 до 1 (0% - 100%) и устанавливает громкость звуков.

Есть похожая функция, но которая называется audio_set_master_gain(ID слушателя, Громкость). Соответственно, она необходима нам в том случае, если у нас несколько "слушателей". Полезно при создании мультиплеера, либо для того, чтобы позволить нашему ИИ ориентироваться на звук.
Результат:

Заставим человечков издавать звук.

Прежде, чем приступим, немного теории.
Мы ведь не хотим, чтобы те звуки, которые есть в комнате, были слышны ото всюду, верно? Следовательно, нам нужно использовать немного другой подход к созданию звуков.
Чтобы в дальнейшем иметь возможность на эти звуки влиять, предлагаю воспользоваться эмиттером - или излучателем.
Делать он будет ровно то, о чем говорится в его названии: излучать звук.
А ещё мы сможем его настроить таким образом, чтобы звук был слышен только на определённом расстоянии от излучателя, а также начинал затухать спустя определённое расстояние.

Здесь всё предельно просто.
Перейдём к oCharPlayer и создадим у него событие - alarm 0. Это событие - "будильник", или, если по нормальному, таймер, в котором будет работать код раз в определённое количество кадров. А теперь пошагово:

Create:

s_emit = audio_emitter_create(); // Создаём эмиттер.
audio_max_dist = CellWidth * 6; // Макс. расстояние, на котором будет слышно звук
audio_fall_at = CellWidth * 2; // Расстояние, на котором звук начнёт "падать"
audio_falloff_set_model(audio_falloff_linear_distance); // Указываем модель, по которой будет происходить затухание звука
audio_emitter_position(s_emit, x, y, 0); // Устанавливаем стартовую позицию эмиттера.
audio_emitter_falloff(s_emit, audio_fall_at, audio_max_dist, 1); // Устанавливаем затухание.
var len = audio_sound_length(sndButton); // Узнаём длину звука в секундах.
audio_play_sound_on(s_emit, sndButton, false, 1); // Говорим звуку играть.
alarm[0] = room_speed * len; // Запускаем бесконечный таймер, где будет проигрываться звук.
Alarm 0:
var len = audio_sound_length(sndButton);
audio_play_sound_on(s_emit, sndButton, false, 1);
alarm[0] = room_speed * len;
Step:
audio_emitter_position(s_emit, x, y, 0);
Весь код нужно добавлять в конец существующих событий соответственно.
Итак, что у нас получилось? Сейчас увидим.

Как видно, звук перемещается вместе с нашими человечками. Накладывается друг на друга, но играет строго раз в определённый отрезок времени, успевая полностью "проиграться".

Музыка.

По аналогии с oSSound, создадим oSMusic. Разница в том, что в oSMusic мы в Create сразу пропишем переменную music, равную 0.1. Она и будет отвечать у нас за громкость музыки. Соответственно, нужно sound заменить на music в коде и всё.

Создаём файл для музыки: sndMusic
Заходим в Tools -> Audio Groups. Создаём аудио группу под названием audio_music.
Жмакаем "add asset" и выбираем sndMusic.

Теперь перейдём к oGameManager.
В Create допишем:

if !audio_group_is_loaded(audio_music)
{
audio_group_load(audio_music);
}
audio_group_set_gain(audio_music, 0.1, 0)
Следом в Step:
if !audio_is_playing(sndMusic)
{
audio_play_sound(sndMusic, 10, true)
}
По сути, обозначенный выше код будет загружать нашу аудио группу музыки в память и начнёт её проигрывать.

Тест звука.

Немного бонусов.

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

Для примера - в проекте советую открыть код для oGBuilding и oCell.
Также дополнил код для игрока, чтобы данную систему можно было спокойно тестировать и работать с ней.
Там же в проекте встроен сделан скрипт по созданию прямоугольных областей с заполнением или без.
Соответственно, где заполнения нет - обводка только по периметру.

Там так-то всё просто. Общая логика работы следующая:
Когда нажали (разово) левую кнопку мыши, мы запоминаем координаты клетки, на которую были наведены.
Далее, отдельно проверяем: если кнопка мыши зажата и координаты первой клетки запомнены, на постоянной основе обновляем координаты второй. Заодно создаём прямоугольник с заполнением или без.
Ну и при отпускании ЛКМ - проверяем, что первая координата у нас задана, обновляем картинку и обнуляем все использованные переменные.

Соответственно, как это выглядит при работе:

Ссылка на проект

Сайт, откуда можно брать бесплатные ассеты: звуки, музыку, спрайты и прочее.
Либо из маркета YoYo. На ваше усмотрение.

Серия гайдов подошла к концу. У нас есть заготовка, которую остаётся дорабатывать, рефакторить и всячески дополнять, чтобы создать полноценную игру. Впрочем, это не значит, что я перестану писать всякие статейки, нет.
Буду и дальше разбирать интересные темы, делиться скриптами и заодно рассказывать о ходе работы над проектом.
На повестке: моддинг без кода ( для игроков:D )

Спасибо всем за тёплые слова и поддержку.
До скорых встреч.

Лига Разработчиков Видеоигр

6.7K постов22.2K подписчика

Добавить пост

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"