Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 25.10.2018

Просмотров: 7580

Скачиваний: 136

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

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;


background image

Управление звуком

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;

}


background image

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.

ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ

РАБОТЫ СО ЗВУКОМ

При проигрывании звука важным может оказаться

расстояние до источника звука, так как у звуков в реаль
ном мире наблюдается затухание в зависимости от расстоя


background image

Управление звуком

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) и координаты источ
ника звука (xy).

if (gameManager.player === null) return;

Если не определен игрок, то невозможно посчитать

расстояние до источника звука, тогда осуществляется вы
ход из функции без проигрывания звука.

var viewSize = Math.max(mapManager.view.w, mapManager.view.h) *

0.8;

Создается новая переменная viewSize, которая опре

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


background image

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 менеджера звуков,

в котором настроена громкость в соответствии с расстоя
нием от игрока до источника звука.

Изменение уровня громкости в зависимости от рас

стояния до источника — полезная функция, но иногда
пользователю необходимо приостановить или выключить
воспроизведение звуков.