BGT — sound_pool

Всем привет. Давно я не писал статей по bgt, настало время их продолжить, чтобы и в России появлялись люди, способные создать достаточно качественные аудио игры.
Сегодня мы поговорим о очень полезном дополнении в bgt, как sound_pool
Этот файл находится в корне движка в папке include и очень помогает при написании маломальски сложных игр.
sound_pool — набор объектов, позволяющих достаточно быстро работать со звуками.
Давайте приведу простой пример:
#include»sound_positioning.bgt»;
sound test;
int player_x=1;
int player_y=1;
int object_x=5;
int object_y=7;
void main() {
show_game_window(«Тестируем обычное применение звуков вручную»);
test.load(«test.wav»);
while(true) {
position_sound_2d(test, player_x, player_y, object_x, object_y, 1, 1, 1);
test.play_looped();
if(key_pressed(KEY_RIGHT))
player_x+=1;
if(key_pressed(KEY_LEFT))
player_x-=1;
if(key_pressed(KEY_UP))
player_y+=1;
if(key_pressed)KEY_DOWN))
player_y-=1;
if(key_pressed(KEY_ESCAPE))
exit();
}
}
Объясню пример:
Есть координаты игрока, есть координаты объекта, с помощью стрелок мы можем двигаться к объекту, либо отдаляться от него.
При этом я использовал простое позиционирование звука.
Теперь покажу тот же пример, но с использованием sound_pool
#include»sound_pool.bgt»;
sound_pool s;
int player_x=1;
int player_y=1;
int object_x=5;
int object_y=7;
void main() {
show_game_window(«Тестируем sound pool»);
s.play_2d(«test.wav», player_x, player_y, object_x, object_y, true);
while(true) {
if(key_pressed(KEY_RIGHT))
player_x+=1;
if(key_pressed(KEY_LEFT))
player_x-=1;
if(key_pressed(KEY_UP))
player_y+=1;
if(key_pressed)KEY_DOWN))
player_y-=1;
if(key_pressed(KEY_ESCAPE))
exit();
s.update_listener_2d(player_x, player_y);
}
}
Видите разницу? Здесь мы написали поменьше кода.
Но это не все преимущества sound_pool.
Представьте, что у вас игра с множеством пространств.
Допустим сначала у вас на 50 клеток квадрат леса, далее на 50 клеток квадрат степи ну и так далее.
Встаёт вопрос, как сделать постоянным звук леса в лесу, но чтобы он плавно перетекал в звук степи, если игрок подошёл к краю леса и как сделать, чтобы звук леса плавно удалился, когда игрок войдёт в степь?
Конечно можно спрограммировать всё это при помощи volume у любого звука, но это, согласитесь, тупо и ненадёжно.
sound_pool позволяет сделать это за написание одной строки.
Итак, мы поняли, что всё-таки использовать sound_pool гараздо удобнее, и приступим к его изучению.
Как вы уже поняли, это тоже стандартное дополнение для bgt, которое необходимо подключать в начале скрипта.
#include»sound_pool.bgt»;
Далее необходимо создать объект sound_pool.
sound_pool s;
Вы можете дать этому объекту имя не s, а то, которое для вас лучше. Здесь правила те же, что и для переменных и прочего.
Далее уже делаем всё, что хотим.
У sound_pool есть основные функции, которые используются в 90% случаях.
play_stationary(имя файла, цикл);
Первый параметр задаёт имя файла в кавычках. Второй параметр может принимать 2 значения true и false.
Если true, то звук будет проигрываться постоянно, если же false, то звук проиграется один раз и замолчит.
Эта функция будет проигрывать звук строго по середине без всяких там 1d и 2d
play_stationary_extended(имя файла, цикл, точка старта, панарама, громкость, тональность, false);
имя файла задаётся в кавычках.
что такое цикл, вы уже поняли из предыдущей функции.
точка старта позволяет нам проигрывать файл не сначала, а с определённого места. Как раз вместо точки старта пишут к примеру 1000, чтобы файл начал проигрываться после первой секунды воспроизведения.
панарама задаёт звучание звука в наушниках. если будет 100, то звук будет только справа, если будет значение 0, то звук будет, как обычно, по середине, а если значение будет -100, то звук будет чисто слева.
Громкость задаёт громкость звука. если 0, то громкость будет обычной, если отрицательное значение, то громкость будет уменьшаться, если положительное, то громкость будет увеличиваться.
Тональность задаёт тон звука. стандартный тон звука всегда 100, если вы хотите слышать звук ниже по тональности, то ставьте значение меньше ста, если выше, то ставьте значение выше ста.
Последний параметр всегда долже принимать значение false.
Я долго изучал справочник, но так и не понял, зачем нужен этот параметр. Однако спокойно всё делал без него.
Просто ставьте всегда в false и всё будет хорошо.
Эта функция позволяет проигрывать звук с изменёнными параметрами.
play_1d(имя файла, позиция игрока, позиция звука, цикл);
Помните, мы рассматривали position_sound, так вот тут почти тоже самое. нужна позиция, относительно которой будет проигрываться звук, нужна позиция этого самого звука.
к примеру:
s.play_1d(«enemy.wav», player_x, enemy_x, true);
Эта функция проигрывает звук в 1d пространстве. Вы наверняка играли в сайд-скроллеры и должны знать, что звук там только слева и справа. вот эта функция делает такую позицию звука.
play_extended_1d(имя файла, позиция игрока, позиция звука, левый край звука, правый край звука, цикл, точка старта, панарама, громкость, тональность, false);
Тут всё также, как и в play_1d и в play_stationary_extended, но есть 2 параметра, с которыми мы ещё не сталкивались.
левый и правый края звука.
Эти параметры задают значение, при котором звук будет проигрываться, даже если игрок уже прошёл его позицию, либо не дошёл до неё.
Например у вас есть сайд-скроллер, в котором игрок идёт вправа, а перед ним озеро. Озеро ведь большое, не на одну клетку явно. допустим, что оно у нас будет на 11 клеток.
Позиция звука озера будет к примеру 25.
Но звук воды должен распространяться на 11 клеток.
Вот тут нам помогут эти параметры. пишем так:
s.play_extended_1d(«lake.wav», player_x, lake_x, 5, 5, true, 0, 0, 0, 100, false);
Таким образом наш звук озера будет проигрываться по середине даже на 5 клеток от самой позиции звука.
play_2d(имя файла, x координата игрока, y координата игрока, x координата звука, y координата звука, цикл);
Это тоже самое, что и play_1d, только в 2д среде. Здесмь нужны координаты игрока x и y, нужны координаты звука x и y.
Также для 2д среды есть и play_extended_2d(имя файла, x координата игрока, y координата игрока, x координата звука, y координата звука, левый край звука, правый край звука, передний край звука, задний край звука, цикл, точка старта, панарама, громкость, тональность, false);
Тут всё также, но добавляются ещё 2 параметра. задний и передний края. Они позволяют распространить звук по заданной площади не только слева и справа, но и спереди и сзади.
Думаю, что тут всё понятно.
Ещё необходимо знать такую вещь, как назначение переменных звукам.
int slot=s.play_2d(«sound.wav», x, y, s_x, s_y, true);
Мы назначили проигрывание звука определённой переменной slot.
Теперь именно с этим звуком мы можем делать, что захотим. Например есть очень полезная функция остановки звука.
s.pause_sound(slot);
Теперь наш звук, находящийся в переменной slot, перестанет проигрываться.
Есть и функция, позволяющая вновь воспроизвести наш звук.
s.resume_sound(slot);
Звук вновь начнёт проигрывание.
Также есть очень необходимая функция, как update_sound_1d(переменная звука, позиция звука);
Представьте, что у вас в игре летают какие-нибудь мухи, они постоянно жужжат. Если вы просто зададите мухе координаты, зададите движение, то сама муха будет двигаться, а вот её звук не будет.
Для этого служит функция обновления звука.
s.update_sound_1d(fly_slot, fly_x);
Эту функцию следует писать в основном цикле игры while(true) который.
Схожая функция и для 2д среды.
s.update_sound_2d(fly_slot, fly_x, fly_y);
Также есть нужная очень функция update_listener_1d(player_x);
Она обновляет все звуки относительно заданной переменной. Если у вас в игре есть 1д или 2д среда, то такие функции нужно использовать в цикле игры.
тоже самое и с 2д.
update_listener_2d(x, y);
Ещё очень нужные функции это уничтожение всех звуков и звука с определённой переменной.
Допустим игрок нажимает клавишу escape и из игры попадает в меню. При этом звуки-то в игре остались. А что делать в таком случае?
Тут нам понадобится функция уничтожения всех звуков.
s.destroy_all();
Всё! все звуки замолчат.
А если вам нужно, чтобы замолчал определённый звук, то нужна сначала его переменная, к примеру sound_slot, и пишем такую функцию:
s.destroy_sound(sound_slot);
Ну и на последок приведу пример использования всех функций, чтобы стало понятно, как и где их использовать.
#include»sound_pool.bgt»;
sound_pool sounds;
//переменные игрока
int x=1;
int y=1;
//переменные озера
int lake_x=5;
int lake_y=5;
//переменные мухи
int fly_x=20;
int fly_y=1;
//переменная для мухи
int fly_slot;
//Таймер ходьбы
timer step;
//таймер движения мухи
timer fly_move;
void main() {
show_game_window(«Тест»);
//Воспроизводим звук озера на 5 клеток вокруг
sounds.play_extended_2d(«lake.wav», x, y, lake_x, lake_y, 5, 5, 5, 5, true, 0, 0, 0, 100, false);
//воспроизводим звук мухи
fly_slot=sounds.play_2d(«fly.wav», x, y, fly_x, fly_y, true);
while(true) {
//Обновление звука мухи
sounds.update_sound_2d(fly_slot, fly_x, fly_y);
//движение мухию. муха будет лететь влева. Если муха долетает до озера, она умирает.
if(fly_move.elapsed>80) {
fly_x-=1;
fly_move.restart();
}
if(fly_x==10)
sounds.destroy_sound(fly_slot);
//движение игрока
if(key_down(KEY_UP) and step.elapsed>250) {
y+=1;
sounds.play_stationary(«step»+random(1, 3)+».wav», false);
step.restart();
}
if(key_down(KEY_DOWN) and step.elapsed>250) {
y-=1;
sounds.play_stationary(«step»+random(1, 3)+».wav», false);
step.restart();
}
if(key_down(KEY_LEFT) and step.elapsed>250) {
x-=1;
sounds.play_stationary(«step»+random(1, 3)+».wav», false);
step.restart();
}
if(key_down(KEY_RIGHT) and step.elapsed>250) {
x+=1;
sounds.play_stationary(«step»+random(1, 3)+».wav», false);
step.restart();
}
sounds.update_listener_2d(x, y);
if(key_pressed(KEY_ESCAPE)) {
sounds.destroy_all();
alert(«Сообщение», «Вы покинули игру.»);
exit();
}
}
}
Ну вот и всё вроде. Всем удачи и продвижения. Да, если найдёте ошибку в статье, оставьте замечание в комментах. Ведь человек не робот. Может и ошибиться.
Все непонятки тоже оставляем в комментах к статье, либо на адресс Anton.Bogatov@list.ru