Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf
Добавлен: 25.10.2018
Просмотров: 7580
Скачиваний: 136
116
Глава 7
В результате выполнения функции load будет загру
жен в браузер пользователя один аудиофайл.
function loadArray(array) { // çàãðóçèòü ìàññèâ çâóêîâ
for (var i = 0; i < array.length; i++) {
soundManager.load(array[i], function () {
if (array.length ===
Object.keys(soundManager.clips).length) {
// åñëè ïîäãîòîâèëè äëÿ çàãðóçêè âñå çâóêè
for (sd in soundManager.clips)
if (!soundManager.clips[sd].loaded) return;
soundManager.loaded = true; // âñå çâóêè çàãðóæåíû
}
}); // êîíåö soundManager.load
} // êîíåö for
}
Функция loadArray предназначена для загрузки мас
сива аудиофайлов (array).
for (var i = 0; i < array.length; i++)
Выполняется цикл for по всем элементам массива array.
soundManager.load(array[i], function () { });
Для каждого элемента массива выполняется функция
загрузки (load), которой в качестве первого параметра пе
редается путь до файла, а в качестве второго параметра —
функция, которая будет выполнена после успешной за
грузки файла. Рассмотрим построчно эту функцию.
if (array.length === Object.keys(soundManager.clips).length)
Проверяется, что длина массива равна количеству кли
пов, подготовленных для загрузки. В данном случае кли
пы хранятся не в массиве, поэтому для определения их
количества используется встроенная функция keys объек
та Object, которая возвращает имена полей объекта в виде
массива, затем у полученного массива определяется дли
на (length).
for (sd in soundManager.clips)
Выполняется цикл for по всем клипам (sd) из поля clips
менеджера звуков.
if (!soundManager.clips[sd].loaded) return;
Управление звуком
117
Если аудиофайл, соответствующий данному клипу, не
загружен, то осуществляется выход из функции.
soundManager.loaded = true;
Если в результате выполнения цикла не выполнен вы
ход из функции, значит все аудиофайлы загружены.
После загрузки аудиофайлов возможно их проигры
вание.
function play(path, settings) {
if (!soundManager.loaded) { // åñëè åùå âñå íå çàãðóçèëè
setTimeout(function () { soundManager.play(path, settings); },
1000);
return;
}
var looping = false; // çíà÷åíèÿ ïî óìîë÷àíèþ
var volume = 1;
if (settings) { // åñëè ïåðåîïðåäåëåíû, òî ïåðåíàñòðàèâàåì
çíà÷åíèÿ
if (settings.looping)
looping = settings.looping;
if (settings.volume)
volume = settings.volume;
}
var sd = this.clips[path]; // ïîëó÷àåì çâóêîâîé ýôôåêò
if (sd === null)
return false;
// ñîçäàåì íîâûé ýêçåìïëÿð ïðîèãðûâàòåëÿ BufferSource
var sound = soundManager.context.createBufferSource();
sound.buffer = sd.buffer;
sound.connect(soundManager.gainNode);
sound.loop = looping;
soundManager.gainNode.gain.value = volume;
sound.start(0);
return true;
}
Функция play принимает два параметра: путь до аудио
файла, который необходимо проиграть, и параметры звука.
if (!soundManager.loaded) {
setTimeout(function () { soundManager.play(path, settings); }, 1000);
return;
}
118
Глава 7
Условие проверит, загружены ли звуки, если нет, то с
использованием встроенной функции setTimeout выпол
няется задержка на 1 с и повторяется вызов функции play.
var looping = false;
var volume = 1;
Настраиваются значения по умолчанию для перемен
ной looping (проигрывание в цикле) и volume (громкость).
if (settings)
Проверяется, что существует переменная settings.
if (settings.looping) looping = settings.looping;
Если существует переменная settings.looping, то ее
значение сохраняется в переменной looping. В следующей
строке аналогичные действия выполняются для перемен
ной volume:
var sd = this.clips[path];
Создается новая переменная sd, в которую сохраняет
ся клип из объекта clips.
if (sd === null) return false;
Если клип с заданным именем не найден, то осуществ
ляется выход из функции play без проигрывания звука.
Остальные строки функции play идентичны программ
ному коду из параграфа 7.1 «Проигрывание аудиофайлов
с настройкой громкости звука». Отличие заключается
только в одной строке:
sound.buffer = sd.buffer;
Поток байт хранится в клипе (sd) в поле buffer.
В результате вызова функции play будет выполнено
проигрывание загруженного аудиофайла.
7.3.
ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ
РАБОТЫ СО ЗВУКОМ
При проигрывании звука важным может оказаться
расстояние до источника звука, так как у звуков в реаль
ном мире наблюдается затухание в зависимости от расстоя
Управление звуком
119
ния. В связи с этим целесообразно в менеджере звуков ре
ализовать метод проигрывания, который будет учитывать
расстояние до источника.
function playWorldSound(path, x, y) { // êàêîé çâóê è ãäå õîòèì ïðîèãðàòü
// íàñòðîéêà çâóêà â çàâèñèìîñòè ðàññòîÿíèÿ îò èãðîêà
if (gameManager.player === null)
return;
// ìàêñèìàëüíàÿ ñëûøèìàÿ îáëàñòü 80% îò ðàçìåðà õîëñòà
var viewSize = Math.max(mapManager.view.w, mapManager.view.h)
* 0.8;
var dx = Math.abs(gameManager.player.pos_x - x);
var dy = Math.abs(gameManager.player.pos_y - y);
var distance = Math.sqrt(dx * dx + dy * dy);
var norm = distance / viewSize; // îïðåäåëÿåì äèñòàíöèþ
// äî èñòî÷íèêà çâóêà
if (norm > 1)
norm = 1;
var volume = 1.0 - norm;
if (!volume) // åñëè íå ñëûøíî, òî íå èãðàåì
return;
soundManager.play(path, {looping: false, volume: volume});
}
Функция playWorldSound принимает в качестве па
раметра путь до аудиофайла (path) и координаты источ
ника звука (x, y).
if (gameManager.player === null) return;
Если не определен игрок, то невозможно посчитать
расстояние до источника звука, тогда осуществляется вы
ход из функции без проигрывания звука.
var viewSize = Math.max(mapManager.view.w, mapManager.view.h) *
0.8;
Создается новая переменная viewSize, которая опре
деляет максимальное расстояние до источника звука, ко
торое будет воспроизводиться. Чем ближе к игроку, тем
звук будет воспроизводиться громче, чем дальше — тем
120
Глава 7
тише. Изменение громкости будет выполняться по линей
ному закону.
var dx = Math.abs(gameManager.player.pos_x - x);
var dy = Math.abs(gameManager.player.pos_y - y);
В переменных dx и dy сохраняется расстояние до источ
ника звука по горизонтали и по вертикали.
var distance = Math.sqrt(dx * dx + dy * dy);
В переменную distance сохраняется расстояние до
источника звука по прямой, вычисленной по правилу тре
угольника — квадрат гипотенузы равен сумме квадратов
катетов. Встроенная функция sqrt объекта Math вычис
ляет квадратный корень.
var norm = distance / viewSize;
В переменную norm сохраняется нормированное рас
стояние до источника звука.
if (norm > 1) norm = 1;
Если расстояние слишком велико, то устанавливаем
norm в 1.
var volume = 1.0 - norm;
Уровень громкости (volume) линейно зависит от зна
чения norm, зависимость обратная. Чем ближе источник
звука, тем volume больше.
if (!volume) return;
Если volume оказался равным нулю, то звук не проиг
рывается и осуществляется выход из функции.
soundManager.play(path, {looping: false, volume: volume});
Выполняется вызов функции play менеджера звуков,
в котором настроена громкость в соответствии с расстоя
нием от игрока до источника звука.
Изменение уровня громкости в зависимости от рас
стояния до источника — полезная функция, но иногда
пользователю необходимо приостановить или выключить
воспроизведение звуков.